Compare commits

...

249 Commits

Author SHA1 Message Date
Adam Langley ea2d217b9b Allow CECPQ1 cipher suites to do False Start.
Since they include an ECDHE exchange in them, they are equally-well
suited to False Start.

Change-Id: I75d31493a614a78ccbf337574c359271831d654d
Reviewed-on: https://boringssl-review.googlesource.com/8732
Reviewed-by: David Benjamin <davidben@google.com>
2016-07-14 18:35:46 -07:00
Adam Langley 3cab5572b1 Don't align NEWPOLY_POLY.
The alignas in NEWPOLY_POLY told the compiler that it could assume a
certain alignment. However, values were allocated with malloc with no
specific alignment.

We could try and allocate aligned memory but the alignment doesn't have
a performance impact (on x86-64) so this is the simpler change. (Also,
Windows doesn't have |posix_memalign|. The cloest thing is
_alligned_alloc but then one has to use a special free function.)

Change-Id: I53955a88862160c02aa5436d991b1b797c3c17db
Reviewed-on: https://boringssl-review.googlesource.com/8315
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-16 17:48:08 +00:00
Brian Smith 13603a8399 Move "no inverse" test earlier in |BN_mod_inverse_no_branch|.
There's no use doing the remaining work if we're going to fail due to
there being no inverse.

Change-Id: Ic6d7c92cbbc2f7c40c51e6be2de3802980d32543
Reviewed-on: https://boringssl-review.googlesource.com/8310
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-16 17:05:55 +00:00
Steven Valdez 7975056ac1 Fixing iv_length for TLS 1.3.
In TLS 1.3, the iv_length is equal to the explicit AEAD nonce length,
and is required to be at least 8 bytes.

Change-Id: Ib258f227d0a02c5abfc7b65adb4e4a689feffe33
Reviewed-on: https://boringssl-review.googlesource.com/8304
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-16 17:04:14 +00:00
Matt Braithwaite 3675dddab9 newhope_test: corrupt things harder.
This ensures that the test is not flaky after lots of iterations.

Along the way, change newhope_test.cc to C++.

Change-Id: I4ef139444b8c8a98db53d075105eb6806f6c5fc7
Reviewed-on: https://boringssl-review.googlesource.com/8110
Reviewed-by: Adam Langley <agl@google.com>
2016-06-16 16:41:19 +00:00
David Benjamin da7f0c65ef Unwind X509_LU_RETRY and fix a lot of type confusion.
(This change will be sent upstream. Since the legacy X.509 stack is just
kept around for compatibility, if they decide to fix it in a different
way, we may wish to revert this and apply their fix.)

Dating back to SSLeay, X509_LOOKUP_METHOD had this X509_LU_RETRY
machinery. But it's not documented and it appears to have never worked.

Problems with the existing logic:

- X509_LU_* is not sure whether it is a type enum (to be passed into
  X509_LOOKUP_by_*) or a return enum (to be retained by those same
  functions).

- X509_LOOKUP_by_* is not sure whether it returns 0/1 or an X509_LU_*
  value.  Looking at the functions themselves, one might think it's the
  latter, but for X509_LOOKUP_by_subject returning both 0 and
  X509_LU_FAIL. But looking at the call sites, some expect 0/1 (such as
  X509_STORE_get1_certs) while others expect an X509_LU_* enum (such as
  X509_STORE_CTX_get1_issuer). It is very fortunate that FAIL happens to
  be 0 and X509 happens to be 1.

  These functions primarily call to X509_LOOKUP_METHOD hooks. Looking
  through OpenSSL itself and code checked into Google, I found no
  evidence that any hooks have been implemented except for
  get_by_subject in by_dir.c. We take that one as definitive and observe
  it believes it returns 0/1. Notably, it returns 1 on success even if
  asked for a type other than X509_LU_X509. (X509_LU_X509 = 1. Others are
  different.) I found another piece of third-party software which corroborates
  this worldview.

- X509_STORE_get_by_subject's handling of X509_LU_RETRY (it's the j < 0
  check) is broken. It saves j into vs->current_method where it probably
  meant to save i. (This bug has existed since SSLeay.)

  It also returns j (supposedly X509_LU_RETRY) while all callers of
  X509_STORE_get_by_subject expect it to return 0/1 by checking with !
  instead of <= 0. (Note that all other codepaths return 0 and 1 so this
  function did not actually believe it returned X509_LU_* most of the
  time.)

  This, in turn, gives us a free of uninitialized pointers in
  X509_STORE_get1_certs and other functions which expect that *ret is
  filled in if X509_STORE_get_by_subject returns success. GCC 4.9 with
  optimizations from the Android NDK noticed this, which trigged this
  saga.

  (It's only reachable if any X509_LOOKUP_METHOD returned
  X509_LU_RETRY.)

- Although the code which expects X509_STORE_get_by_subject return 0/1
  does not date to SSLeay, the X509_STORE_get_by_subject call in
  X509_STORE_CTX_get1_issuer *does* (though, at the time, it was inline
  in X509_verify_cert. That code believes X509_STORE_get_by_subject
  returns an X509_LU_* enum, but it doesn't work either! It believes
  *ret is filled in on X509_LU_RETRY, thus freeing another uninitialized
  pointer (GCC noticed this too).

Since this "retry" code has clearly never worked, from SSLeay onwards,
unwind it completely rather than attempt to fix it. No
X509_LOOKUP_METHOD can possibly have depended on it.

Matching all non-broken codepaths X509_LOOKUP_by_* now returns 0/1 and
X509_STORE_get_by_subject returns 0/1. X509_LU_* is purely a type enum
with X509_LU_{REJECT,FAIL} being legacy constants to keep old code
compiling. (Upstream is recommended to remove those values altogether
for 1.1.0.)

On the off chance any get_by_* X509_LOOKUP_METHOD implementations did
not return 0/1 (I have found no evidence anywhere of this, and I believe
it wouldn't have worked anyway), the X509_LOOKUP_by_* wrapper functions
will coerce the return values back to 0/1 before passing up to the
callers which want 0/1. This both avoids the error-prone -1/0/1 calling
convention and, more importantly, avoids problems with third-party
callers which expect a X509_LU_* return code. 0/1 collide with FAIL/X509
while -1 will collide with RETRY and might confuse things.

Change-Id: I98ecf6fa7342866b9124dc6f0b422cb9ce4a1ae7
Reviewed-on: https://boringssl-review.googlesource.com/8303
Reviewed-by: Adam Langley <agl@google.com>
2016-06-16 16:24:44 +00:00
David Benjamin 054e597670 Include intrin.h under cover of warning pragmas.
intrin.h on MSVC seems to have the same problem as other MSVC headers.
https://build.chromium.org/p/client.boringssl/builders/win64_small/builds/455/steps/ninja/logs/stdio

Change-Id: I98e959132c2f6188727d6c432f9c85aa0a78e91e
Reviewed-on: https://boringssl-review.googlesource.com/8305
Reviewed-by: Adam Langley <agl@google.com>
2016-06-16 16:12:32 +00:00
Nico Weber 2b360714ab win: Add an explicit intrin.h include to work around a clang-cl bug.
I did the same change in NaCl in
https://codereview.chromium.org/2070533002/.  I thought NaCl is the only
place where this was needed, but at least it's due to SecureZeroMemory()
again.  So it's two files now, but at least there's only one function we
know of that needs this, and it's only called in three files total in
all projects used by Chromium.

BUG=chromium:592745

Change-Id: I07ed197869e26ec70c1f4b75d91fd64abae5015e
Reviewed-on: https://boringssl-review.googlesource.com/8320
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-16 16:03:46 +00:00
David Benjamin 80ef433359 No-op change to kick the bots.
Change-Id: Ifed0b7e23bb4df191628486b0c07c888056c22a8
2016-06-15 17:46:31 -04:00
David Benjamin f8fcdf399c Add tests for both Channel ID and NPN together.
Both messages go between CCS and Finished. We weren't testing their relative
order and one of the state machine edges. Also test resume + NPN since that too
is a different handshake shape.

Change-Id: Iaeaf6c2c9bfd133103e2fb079d0e5a86995becfd
Reviewed-on: https://boringssl-review.googlesource.com/8196
Reviewed-by: Adam Langley <agl@google.com>
2016-06-15 21:32:33 +00:00
David Benjamin 65dac9c8a3 Fix the name of OPENSSL_add_all_algorithms_conf.
I named the compatibility function wrong.

Change-Id: Idc289c317c5826c338c1daf58a2d3b26b09a7e49
Reviewed-on: https://boringssl-review.googlesource.com/8301
Reviewed-by: Adam Langley <agl@google.com>
2016-06-15 21:29:50 +00:00
David Benjamin 41e08045f7 Fix typo.
Change-Id: I7699d59e61df16f2091c3e12607c08333dcc9813
Reviewed-on: https://boringssl-review.googlesource.com/8280
Reviewed-by: Adam Langley <agl@google.com>
2016-06-14 19:57:35 +00:00
David Benjamin f715c42322 Make SSL_set_bio's ownership easier to reason about.
SSL_set_bio has some rather complex ownership story because whether rbio/wbio
are both owning depends on whether they are equal. Moreover, whether
SSL_set_bio(ssl, rbio, wbio) frees ssl->rbio depends on whether rbio is the
existing rbio or not. The current logic doesn't even get it right; see tests.

Simplify this. First, rbio and wbio are always owning. All the weird ownership
cases which we're stuck with for compatibility will live in SSL_set_bio. It
will internally BIO_up_ref if necessary and appropriately no-op the left or
right side as needed. It will then call more well-behaved ssl_set_rbio or
ssl_set_wbio functions as necessary.

Change-Id: I6b4b34e23ed01561a8c0aead8bb905363ee413bb
Reviewed-on: https://boringssl-review.googlesource.com/8240
Reviewed-by: Adam Langley <agl@google.com>
2016-06-14 19:40:25 +00:00
David Benjamin 5c0fb889a1 Add tests for SSL_set_fd and friends.
Their implementations expose a lot of really weird SSL_set_bio behavior. Note
that one test must be disabled as it doesn't even work. The subsequent commit
will re-enable it.

Change-Id: I4b7acadd710b3be056951886fc3e073a5aa816de
Reviewed-on: https://boringssl-review.googlesource.com/8272
Reviewed-by: Adam Langley <agl@google.com>
2016-06-14 19:38:59 +00:00
Matt Braithwaite dfdd49c961 generate_build_files: more flexible Bazel deps
Include all internal headers in |test_support_sources|, since that's
easier than enumerating the ones specifically required for each test.

This incidentally removes test headers from |crypto_internal_headers|
and |ssl_internal_headers|.

Require the crypto and ssl libraries to be passed as arguments to
create_tests(), rather than hardcoding the names :crypto and :ssl

Change-Id: Idcc522298c5baca2a84635ad3a7fdcf6e4968a5a
Reviewed-on: https://boringssl-review.googlesource.com/8260
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-14 19:36:17 +00:00
David Benjamin 7af3140a82 Remove ASN.1 BIOs.
These are more remnants of CMS. Nothing uses them directly. Removing them means
more code we don't have to think about when importing upstream patches.

Also take out a bunch of dead prototypes nearby.

Change-Id: Ife094d9d2078570006d1355fa4e3323f435be608
Reviewed-on: https://boringssl-review.googlesource.com/8244
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-14 17:39:30 +00:00
David Benjamin ae0bf3b7c1 Remove ASN1_parse and ASN1_parse_dump.
These are more pretty-printers for generic ASN.1 structures. They're never
called externally and otherwise are only used in the X509V3_EXT_PARSE_UNKNOWN
mode for the X509 pretty-print functions. That makes unknown extensions
pretty-print as ASN.1 structures.

This is a rather useless feature, so have that fall through to
X509V3_EXT_DUMP_UNKNOWN which does a hexdump instead.

(The immediate trigger is I don't know what |op| is in upstream's
8c918b7b9c93ba38790ffd1a83e23c3684e66f57 and don't think it is worth the time
to puzzle that out and verify it. Better ditch this code completely.)

Change-Id: I0217906367d83056030aea64ef344d4fedf74763
Reviewed-on: https://boringssl-review.googlesource.com/8243
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-14 17:39:17 +00:00
David Benjamin e77b16ef71 Remove ASN.1 print hooks.
These functions are never instantiated. (They're a remnant of the PKCS#7 and
CMS bits.) Next time upstream touches this code, we don't have to puzzle
through the diff and import it.

Change-Id: I67c2102ae13e8e0527d858e1c63637dd442a4ffb
Reviewed-on: https://boringssl-review.googlesource.com/8242
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-14 17:38:31 +00:00
Matt Braithwaite 6278e24a62 shim: fix var unused when asserts compiled out
This is not very satisfactory.

Change-Id: I7e7a86f921e66f8f830c72eac084e9fea5ffd4d9
Reviewed-on: https://boringssl-review.googlesource.com/8270
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-14 15:48:54 +00:00
Matt Braithwaite 54217e4d85 newhope: test corrupt key exchange messages.
By corrupting the X25519 and Newhope parts separately, the test shows
that both are in use.  Possibly excessive?

Change-Id: Ieb10f46f8ba876faacdafe70c5561c50a5863153
Reviewed-on: https://boringssl-review.googlesource.com/8250
Reviewed-by: Adam Langley <agl@google.com>
2016-06-13 23:11:49 +00:00
David Benjamin d0c677cd8e Avoid illegal pointers in asn1_string_canon.
(Imported from upstream's 3892b95750b6aa5ed4328a287068f7cdfb9e55bc.)

More reasonable would have been to drop |to| altogether and act on from[len-1],
but I suppose this works.

Change-Id: I280b4991042b4d330ba034f6a631f8421ddb2643
Reviewed-on: https://boringssl-review.googlesource.com/8241
Reviewed-by: Adam Langley <agl@google.com>
2016-06-13 21:57:05 +00:00
David Benjamin 37e01b393c Spell C++11 as C++11, not C++0x.
We already require GCC 4.8+, so -std=c++11 should work fine.

Change-Id: I07d46d7dcccb695b5df97a702f0d5007fdff3385
Reviewed-on: https://boringssl-review.googlesource.com/8245
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-13 19:20:40 +00:00
David Benjamin f6a74c61f7 Document compiler and assembler requirements.
The minimum version is purely based on what we've patched out of the perlasm
files. I'm assuming they're accurate.

Change-Id: I5ae176cf793512125fa78f203a1314396e8a14d7
Reviewed-on: https://boringssl-review.googlesource.com/8238
Reviewed-by: Adam Langley <agl@google.com>
2016-06-10 17:17:09 +00:00
David Benjamin 171b5403ee Fix ssl3_do_write error handling.
The functions it calls all pass through <= 0 as error codes, not < 0.

Change-Id: I9d0d6b1df0065efc63f2d3a5e7f3497b2c28453a
Reviewed-on: https://boringssl-review.googlesource.com/8237
Reviewed-by: Adam Langley <agl@google.com>
2016-06-09 23:51:08 +00:00
Matt Braithwaite 1669589445 Bazel: allow arbitrary path prefix before 'src'
Change-Id: Ifd8e6466620a92f0d4b79c179bb21e634a930f52
Reviewed-on: https://boringssl-review.googlesource.com/8220
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-09 21:35:16 +00:00
David Benjamin a353cdb671 Wrap MSVC-only warning pragmas in a macro.
There's a __pragma expression which allows this. Android builds us Windows with
MinGW for some reason, so we actually do have to tolerate non-MSVC-compatible
Windows compilers. (Clang for Windows is much more sensible than MinGW and
intentionally mimicks MSVC.)

MinGW doesn't understand MSVC's pragmas and warns a lot. #pragma warning is
safe to suppress, so wrap those to shush them. This also lets us do away with a
few ifdefs.

Change-Id: I1f5a8bec4940d4b2d947c4c1cc9341bc15ec4972
Reviewed-on: https://boringssl-review.googlesource.com/8236
Reviewed-by: Adam Langley <agl@google.com>
2016-06-09 21:29:36 +00:00
David Benjamin 2e8ba2d25d Use one C99-style for loop.
Switch one for loop to the new spelling as a canary. All our compilers seem to
support it fine, except GCC needs to be told to build with -std=c99. (And, upon
doing so, it'll require _XOPEN_SOURCE=700 for pthread_rwlock_t.)

We'll let this sit for a bit until it's gotten into downstreams without issue
and then open the floodgates.

BUG=47

Change-Id: I1c69d4b2df8206e0b55f30aa59b5874d82fca893
Reviewed-on: https://boringssl-review.googlesource.com/8235
Reviewed-by: Adam Langley <agl@google.com>
2016-06-09 21:27:54 +00:00
David Benjamin 95d7a498cc Fix the alias checks in dtls_record.c.
I forgot to save this file.

Change-Id: I8540839fac2a7f426aebd7f2cb85baba337efd37
Reviewed-on: https://boringssl-review.googlesource.com/8234
Reviewed-by: Adam Langley <agl@google.com>
2016-06-09 21:11:22 +00:00
David Benjamin bf1905a910 Revert "Import chacha-x86.pl fix."
This reverts commit 762e1d039c. We no longer need
to support out < in. Better to keep the assembly aligned with upstream.

Change-Id: I345bf822953bd0e1e79ad5ab4d337dcb22e7676b
Reviewed-on: https://boringssl-review.googlesource.com/8232
Reviewed-by: Adam Langley <agl@google.com>
2016-06-09 19:49:12 +00:00
David Benjamin 2446db0f52 Require in == out for in-place encryption.
While most of OpenSSL's assembly allows out < in too, some of it doesn't.
Upstream seems to not consider this a problem (or, at least, they're failing to
make a decision on whether it is a problem, so we should assume they'll stay
their course). Accordingly, require aliased buffers to exactly align so we
don't have to keep chasing this down.

Change-Id: I00eb3df3e195b249116c68f7272442918d7077eb
Reviewed-on: https://boringssl-review.googlesource.com/8231
Reviewed-by: Adam Langley <agl@google.com>
2016-06-09 19:49:03 +00:00
David Benjamin 1a01e1fc88 Remove in-place TLS record assembly for now.
Decrypting is very easy to do in-place, but encrypting in-place is a hassle.
The rules actually were wrong due to record-splitting. The aliasing prefix and
the alignment prefix actually differ by 1. Take it out for now in preparation
for tightening the aliasing rules.

If we decide to do in-place encrypt later, probably it'd be more useful to
return header + in-place ciphertext + trailer. (That, in turn, needs a
scatter/gather thing on the AEAD thanks to TLS 1.3's padding and record type
construction.) We may also wish to rethink how record-splitting works here.

Change-Id: I0187d39c541e76ef933b7c2c193323164fd8a156
Reviewed-on: https://boringssl-review.googlesource.com/8230
Reviewed-by: Adam Langley <agl@google.com>
2016-06-09 19:47:44 +00:00
David Benjamin 67cb49d045 Fix BN_mod_word bug.
On systems where we do not have BN_ULLONG (notably Win64), BN_mod_word() can
return incorrect results if the supplied modulus is too big.

(Imported from upstream's e82fd1b4574c8908b2c3bb68e1237f057a981820 and
e4c4b2766bb97b34ea3479252276ab7c66311809.)

Change-Id: Icee8a7c5c67a8ee14c276097f43a7c491e68c2f9
Reviewed-on: https://boringssl-review.googlesource.com/8233
Reviewed-by: Adam Langley <agl@google.com>
2016-06-09 19:05:31 +00:00
David Benjamin 8f1e113a73 Ensure verify error is set when X509_verify_cert() fails.
Set ctx->error = X509_V_ERR_OUT_OF_MEM when verification cannot
continue due to malloc failure.  Similarly for issuer lookup failures
and caller errors (bad parameters or invalid state).

Also, when X509_verify_cert() returns <= 0 make sure that the
verification status does not remain X509_V_OK, as a last resort set
it it to X509_V_ERR_UNSPECIFIED, just in case some code path returns
an error without setting an appropriate value of ctx->error.

Add new and some missing error codes to X509 error -> SSL alert switch.

(Imported from upstream's 5553a12735e11bc9aa28727afe721e7236788aab.)

Change-Id: I3231a6b2e72a3914cb9316b8e90ebaee009a1c5f
Reviewed-on: https://boringssl-review.googlesource.com/8170
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-09 17:29:39 +00:00
David Benjamin 82d0ffbac1 Use the new setter for CurrentTimeCallback in bssl_shim.
Change-Id: I0aaf9d926a81c3a10e70ae3ae6605d4643419f89
Reviewed-on: https://boringssl-review.googlesource.com/8210
Reviewed-by: Taylor Brandstetter <deadbeef@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 23:26:51 +00:00
Taylor Brandstetter 9edb2c6055 Adding function to set the "current time" callback used for DTLS.
This callback is used by BoringSSL tests in order to simulate the time,
so that the tests have repeatable results. This API will allow consumers
of BoringSSL to write the same sort of tests.

Change-Id: I79d72bce5510bbd83c307915cd2cc937579ce948
Reviewed-on: https://boringssl-review.googlesource.com/8200
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 22:29:25 +00:00
David Benjamin 2e045a980c Add a deterministic PRNG for runner.
It's useful, when combined with patching crypto/rand/deterministic.c in, for
debugging things. Also if we want to record fuzzer transcripts again, this
probably should be on.

Change-Id: I109cf27ebab64f01a13466f0d960def3257d8750
Reviewed-on: https://boringssl-review.googlesource.com/8192
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 20:15:48 +00:00
David Benjamin 1e3376a790 Add missing copyright header.
x25519-x86_64.c, like the rest of crypto/curve25519, is descended from
SUPERCOP. Add the usual copyright header along with the SUPERCOP attribution.

BUG=64

Change-Id: I43f3de0731f33ab2aa48492c4b742e9f23c87fe1
Reviewed-on: https://boringssl-review.googlesource.com/8195
Reviewed-by: Adam Langley <agl@google.com>
2016-06-08 20:13:46 +00:00
David Benjamin 1c0e1e4a33 Avoid overflow in newhope.go.
Depending on bittedness of the runner, uint16 * uint16 can overflow an int.
There's other computations that can overflow a uint32 as well, so I just made
everything uint64 to avoid thinking about it too much.

Change-Id: Ia3c976987f39f78285c865a2d7688600d73c2514
Reviewed-on: https://boringssl-review.googlesource.com/8193
Reviewed-by: Adam Langley <agl@google.com>
2016-06-08 20:10:48 +00:00
David Benjamin 45d45c1194 Trim the DTLS write code slightly.
Change-Id: I0fb4152ed656a60fae3aa7922652df766d4978d7
Reviewed-on: https://boringssl-review.googlesource.com/8178
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 19:33:20 +00:00
David Benjamin 936aada25a Move a bunch of public APIs from s3_lib.c to ssl_lib.c.
The separation is purely historical (what happened to use an SSL_ctrl hook), so
put them all in one place. Make a vague attempt to match the order of the
header file, though we're still very far from matching.

Change-Id: Iba003ff4a06684a6be342e438d34bc92cab1cd14
Reviewed-on: https://boringssl-review.googlesource.com/8189
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 19:27:44 +00:00
David Benjamin 01784b44b9 Rename -timeout to -idle-timeout.
-timeout collides with go test's flags.

Change-Id: Icfc954915a61f1bb4d0acc8f02ec8a482ea10158
Reviewed-on: https://boringssl-review.googlesource.com/8188
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 19:27:35 +00:00
David Benjamin 3dcec458f1 Rename SERVER_DONE to SERVER_HELLO_DONE.
Match the actual name of the type.

Change-Id: I0ad27196ee2876ce0690d13068fa95f68b05b0da
Reviewed-on: https://boringssl-review.googlesource.com/8187
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 19:26:59 +00:00
David Benjamin cfec7c60b9 Rename s3_{clnt,srvr}.c
Give them much more reasonable names.

Change-Id: Id14d983ab3231da21a4f987e662c2e01af7a2cd6
Reviewed-on: https://boringssl-review.googlesource.com/8185
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 19:25:31 +00:00
David Benjamin 9f1dc8254e A bit of cleanup post state machine merging.
Reorder states and functions by where they appear in the handshake. Remove
unnecessary hooks on SSL_PROTOCOL_METHOD.

Change-Id: I78dae9cf70792170abed6f38510ce870707e82ff
Reviewed-on: https://boringssl-review.googlesource.com/8184
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 19:24:32 +00:00
David Benjamin df50eecfbc Fold DTLS server state machine into TLS state machine.
Change-Id: I56d3d625dbe2e338f305bc1332fb0131a20e1c16
Reviewed-on: https://boringssl-review.googlesource.com/8183
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 19:21:14 +00:00
David Benjamin aa7734b81b Fold the DTLS client handshake into the TLS one.
Change-Id: Ib8b1c646cf1652ee1481fe73589830be8263fc20
Reviewed-on: https://boringssl-review.googlesource.com/8182
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 19:20:02 +00:00
David Benjamin 0d21dcd9bb Remove unnecessary sectioning in ssl.h.
There's only one thing under "SNI Extension".

Change-Id: I8d8c54c286cb5775a20c4e2623896eb9be2f0009
Reviewed-on: https://boringssl-review.googlesource.com/8181
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 19:18:45 +00:00
David Benjamin 24fe4489d3 Consolidate dtls1_start_timer calls.
Rather than reset the timer on every message, start it up immediately after
flushing one of our flights.

Change-Id: I97f8b4f572ceff62c546c94933b2700975c50a02
Reviewed-on: https://boringssl-review.googlesource.com/8180
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 19:17:36 +00:00
David Benjamin 2a08c8d85d Remove ssl3_do_write's 0 case.
It's unreachable and wouldn't work anyway. We'd never bubble up to the caller
to retry. As a consequence, the TLS side doesn't actually need to pay attention
to init_off.

(For now anyway. We'll probably need state of this sort once the write half is
all reworked. All the craziness with wpend_buf ought to be limited to the
SSL_write bits.)

Change-Id: I951534f6bbeb547ce0492d5647aaf76be42108a3
Reviewed-on: https://boringssl-review.googlesource.com/8179
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 19:13:37 +00:00
David Benjamin af62d61df3 Remove dtls1_read_bytes.
It can be folded into dtls1_read_app_data. This code, since it still takes an
output pointer, does not yet process records atomically. (Though, being DTLS,
it probably should...)

Change-Id: I57d60785c9c1dd13b5b2ed158a08a8f5a518db4f
Reviewed-on: https://boringssl-review.googlesource.com/8177
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 19:10:35 +00:00
David Benjamin c660417bd7 Don't use dtls1_read_bytes to read messages.
This was probably the worst offender of them all as read_bytes is the wrong
abstraction to begin with. Note this is a slight change in how processing a
record works. Rather than reading one fragment at a time, we process all
fragments in a record and return. The intent here is so that all records are
processed atomically since the connection eventually will not be able to retain
a buffer holding the record.

This loses a ton of (though not quite all yet) those a2b macros.

Change-Id: Ibe4bbcc33c496328de08d272457d2282c411b38b
Reviewed-on: https://boringssl-review.googlesource.com/8176
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 19:09:46 +00:00
David Benjamin 585320c9e9 Don't call read_bytes in read_change_cipher_spec.
Change-Id: If7d50e43c8ea28c5eed38209f31d481fb57bf225
Reviewed-on: https://boringssl-review.googlesource.com/8175
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 18:51:54 +00:00
David Benjamin 4aa4081e7f Don't use ssl3_read_bytes in ssl3_read_close_notify.
read_close_notify is a very straight-forward hook and doesn't need much.

Change-Id: I7407d842321ea1bcb47838424a0d8f7550ad71ca
Reviewed-on: https://boringssl-review.googlesource.com/8174
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 18:39:26 +00:00
David Benjamin a7810c12e9 Make tls_open_record always in-place.
The business with ssl_record_prefix_len is rather a hassle. Instead, have
tls_open_record always decrypt in-place and give back a CBS to where the body
is.

This way the caller doesn't need to do an extra check all to avoid creating an
invalid pointer and underflow in subtraction.

Change-Id: I4e12b25a760870d8f8a503673ab00a2d774fc9ee
Reviewed-on: https://boringssl-review.googlesource.com/8173
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 18:39:07 +00:00
David Benjamin 728f354a2b Push alert handling down into the record functions.
Alert handling is more-or-less identical across all contexts. Push it down from
read_bytes into the low-level record functions. This also deduplicates the code
shared between TLS and DTLS.

Now the only type mismatch managed by read_bytes is if we get handshake data in
read_app_data.

Change-Id: Ia8331897b304566e66d901899cfbf31d2870194e
Reviewed-on: https://boringssl-review.googlesource.com/8124
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 18:35:58 +00:00
David Benjamin ac2920200b Fix typo.
Change-Id: I70499c686b955152840987ffe65d2d3436bf6f6d
Reviewed-on: https://boringssl-review.googlesource.com/8194
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 18:16:14 +00:00
David Benjamin 4e9cc71a27 Add helper functions for info_callback and msg_callback.
This is getting a little repetitive.

Change-Id: Ib0fa8ab10149557c2d728b88648381b9368221d9
Reviewed-on: https://boringssl-review.googlesource.com/8126
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 18:13:53 +00:00
David Benjamin 15aa895a0b Tidy up the DTLS code's blocking-mode retransmits.
Move this logic out of dtls1_read_bytes and into dtls1_get_record. Only trigger
it when reading from the buffer fails. The other one shouldn't be necessary.
This exists to handle the blocking BIO case when the
BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT signal triggers, so we only need to do it when
timeouts actually trigger.

There also doesn't seem to be a need for most of the machinery. The
BIO_set_flags call seems to be working around a deficiency in the underlying
BIO. There also shouldn't be a need to check the handshake state as there
wouldn't be a timer to restart otherwise.

Change-Id: Ic901ccfb5b82aeb409d16a9d32c04741410ad6d7
Reviewed-on: https://boringssl-review.googlesource.com/8122
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 18:13:42 +00:00
David Benjamin 585d7a4987 Test both synchronous and asynchronous DTLS retransmit.
The two modes are quite different. One of them requires the BIO honor an
extra BIO_ctrl. Also add an explanation at the top of
addDTLSRetransmitTests for how these tests work. The description is
scattered across many different places.

BUG=63

Change-Id: Iff4cdd1fbf4f4439ae0c293f565eb6780c7c84f9
Reviewed-on: https://boringssl-review.googlesource.com/8121
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 18:11:41 +00:00
David Benjamin ed9c8fcb23 Honor exit codes in run_android_tests.go.
adb kindly doesn't forward exit codes until N
(https://code.google.com/p/android/issues/detail?id=3254), so we need to work
around it. Otherwise all our test failures have been silently ignored (oops!).

Change-Id: I03440db7dd77e6b9af5445b309b67dc719cea054
Reviewed-on: https://boringssl-review.googlesource.com/8190
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-08 15:45:12 +00:00
David Benjamin 0a45822afe Fix some missing inits
(Imported from upstream's f792c663048f19347a1bb72125e535e4fb2ecf39.)

Change-Id: If9bbb10de3ea858076bd9587d21ec331e837dd53
Reviewed-on: https://boringssl-review.googlesource.com/8171
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-07 22:05:10 +00:00
David Benjamin 26b7c35d8c Fix DSA, preserve BN_FLG_CONSTTIME
Operations in the DSA signing algorithm should run in constant time in
order to avoid side channel attacks. A flaw in the OpenSSL DSA
implementation means that a non-constant time codepath is followed for
certain operations. This has been demonstrated through a cache-timing
attack to be sufficient for an attacker to recover the private DSA key.

CVE-2016-2178

(Imported from upstream's 621eaf49a289bfac26d4cbcdb7396e796784c534 and
b7d0f2834e139a20560d64c73e2565e93715ce2b.)

We should eventually not depend on BN_FLG_CONSTTIME since it's a mess (seeing
as the original fix was wrong until we reported b7d0f2834e to them), but, for
now, go with the simplest fix.

Change-Id: I9ea15c1d1cc3a7e21ef5b591e1879ec97a179718
Reviewed-on: https://boringssl-review.googlesource.com/8172
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-07 19:29:18 +00:00
David Benjamin 0d275bdb32 Don't call ERR_clear_system_error in so many places.
We've got it in entry points. That should be sufficient. (Do we even need it
there?)

Change-Id: I39b245a08fcde7b57e61b0bfc595c6ff4ce2a07a
Reviewed-on: https://boringssl-review.googlesource.com/8127
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-07 15:53:44 +00:00
David Benjamin 4bea8509da Lift an impossible check to an assert.
This cannot happen.

Change-Id: Ib1b473aa91d6479eeff43f7eaf94906d0b2c2a8f
Reviewed-on: https://boringssl-review.googlesource.com/8123
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-06 20:47:07 +00:00
David Benjamin e90d004e00 Remove impossible condition.
ssl->cert is never NULL. It gets created in SSL_new unconditionally.

Change-Id: I5c54c9c73e281e61a554820d61421226d763d33a
Reviewed-on: https://boringssl-review.googlesource.com/8125
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-06 20:33:32 +00:00
David Benjamin 83042a8292 Add a no-op OpenSSL_add_all_algorithms_conf.
More spring-cleaning of unnecessary incompatibilities. Since
OpenSSL_add_all_algorithms_conf doesn't specify a configuration file, it's
perfectly sound to have such a function.

Dear BoringSSL, please add all algorithms.

  Uh, sure. They were already all there, but I have added them!

PS: Could you also load all your configuration files while you're at it.

  ...I don't have any. Fine. I have loaded all configuration files which I
  recognize. *mutters under breath* why does everyone ask all these strange
  questions...

Change-Id: I57f956933d9e519445bf22f89853bd5f56904172
Reviewed-on: https://boringssl-review.googlesource.com/8160
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-06 15:58:02 +00:00
Adam Langley adf27430ef Be consistent about 𝑥_tests.txt
Some files were named 𝑥_test.txt and some 𝑥_tests.txt. This change
unifies around the latter.

Change-Id: Id6f29bad8b998f3c3466655097ef593f7f18f82f
Reviewed-on: https://boringssl-review.googlesource.com/8150
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-06 15:57:46 +00:00
David Benjamin bbc7859817 Match OpenSSL's values for BIO_CTRL_*.
The fake numbers collide with other numbers defined below. Also PUSH and POP
are actually used. DUP legitimately isn't though.

Change-Id: Iaa15a065d846b89b9b7958b78068393cfee2bd6f
Reviewed-on: https://boringssl-review.googlesource.com/8143
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-06 14:51:50 +00:00
David Benjamin f4978b78a0 Add some getters for the old lock callbacks.
Some OpenSSL consumers use them, so provide no-op versions to make porting code
easier.

Change-Id: I4348568c1cb08d2b2c0a9ec9a17e2c0449260965
Reviewed-on: https://boringssl-review.googlesource.com/8142
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-06 14:51:36 +00:00
David Benjamin e7b3ce58ad Add BIO_set_conn_int_port.
Make building against software that expects OpenSSL easier.

Change-Id: I1af090ae8208218d6e226ee0baf51053699d85cc
Reviewed-on: https://boringssl-review.googlesource.com/8141
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-06 14:49:09 +00:00
David Benjamin dbec90b623 Sort out signedness issues.
Windows is, not unreasonably, complaining that taking abs() of an unsigned is
ridiculous. But these values actually are signed and fit very easily in an int
anyway.

Change-Id: I34fecaaa3616732112e3eea105a7c84bd9cd0bae
Reviewed-on: https://boringssl-review.googlesource.com/8144
Reviewed-by: Adam Langley <agl@google.com>
2016-06-03 22:13:30 +00:00
David Benjamin d206dfa91f Add missing newline in newhope.h.
doc.go is still a little unhappy.

Change-Id: I5a8f3da91dabb45d29d0e08f13b7dabdcd521c38
Reviewed-on: https://boringssl-review.googlesource.com/8145
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-03 22:01:13 +00:00
Adam Langley aa80ff50bf crypto/newhope: add OPENSSL_EXPORT to functions used by tests.
Change-Id: Ie6701d6ea809f5c590f0773cb4b733a208553879
2016-06-03 14:45:18 -07:00
Adam Langley a34bd8e38c crypto/newhope: fix comment typo.
Change-Id: Ic7dc57680e8cc8306fb1541249fb356eece30999
2016-06-03 14:37:03 -07:00
Adam Langley 77fe71101b crypto/newhope: print values as unsigneds.
Otherwise builds fail with:
  crypto/newhope/newhope_statistical_test.cc:136:27: error: format specifies type 'long' but the argument has type 'uint64_t' (aka 'unsigned long long') [-Werror,-Wformat]

Change-Id: I85d5816c1d7ee71eef362bffe983b2781ce310a4
2016-06-03 14:32:59 -07:00
Matt Braithwaite 6b7436b0d2 newhope: restore statistical tests.
One of these tests the distribution of noise polynomials; the other
tests that that agreed-upon keys (prior to whitening) have roughly equal
numbers of 0s and 1s.

Along the way, expose a few more API bits.

Change-Id: I6b04708d41590de45d82ea95bae1033cfccd5d67
Reviewed-on: https://boringssl-review.googlesource.com/8130
Reviewed-by: Adam Langley <agl@google.com>
2016-06-03 21:26:18 +00:00
David Benjamin 0fc7df55c0 Add SSL_CIPHER_is_DHE.
Change-Id: I158d1fa1a6b70a278054862326562988c97911b5
Reviewed-on: https://boringssl-review.googlesource.com/8140
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-03 17:57:05 +00:00
Steven Valdez 66af3b0ebc Adding TLS 1.3 Record Layer.
In TLS 1.3, the actual record type is hidden within the encrypted data
and the record layer defaults to using a TLS 1.0 {3, 1} record version
for compatibility. Additionally the record layer no longer checks the
minor version of the record layer to maintain compatibility with the
TLS 1.3 spec.

Change-Id: If2c08e48baab170c1658e0715c33929d36c9be3a
Reviewed-on: https://boringssl-review.googlesource.com/8091
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-02 22:18:48 +00:00
David Benjamin 1a88df13e5 Update style guide note on files which match OpenSSL.
They match the new style not the old EAY style now. They're also not
likely to be reformatted. It's just the legacy ASN.1 stuff now and we're
intentionally not doing much with those. (The old text was written back
before the SSL stack had been reformatted.)

Change-Id: I4852761b013e8c2688ebc7eaf4970afbdc69e858
Reviewed-on: https://boringssl-review.googlesource.com/8129
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-02 21:37:21 +00:00
Steven Valdez 3084e7b87d Adding ECDHE-PSK GCM Ciphersuites.
Change-Id: Iecf534ca0ebdcf34dbf4f922f5000c096a266862
Reviewed-on: https://boringssl-review.googlesource.com/8101
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-02 21:27:16 +00:00
Piotr Sikora 8ca0b4127d Fix X25519 on OS X when using build systems other than CMake.
Assembly code for X25519 wasn't included on OS X when built with
build systems other than CMake, which lead to a SIGTRAP due to a
missing x25519_x86_64.

Reported by Gurgen Hrachyan.

Change-Id: Ib6026f31cce0405ec3e75d8a52bf0940e57c62c8
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Reviewed-on: https://boringssl-review.googlesource.com/8111
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-02 19:48:27 +00:00
Matt Braithwaite 27e863e711 newhope: improve test vectors.
This commit adds coverage of the "offer" (first) step, as well as
testing all outputs of the "accept" (second) step, not just the shared
key.

Change-Id: Id11fe24029abc302442484a6c01fa496a1578b3a
Reviewed-on: https://boringssl-review.googlesource.com/8100
Reviewed-by: Adam Langley <agl@google.com>
2016-06-02 19:28:00 +00:00
David Benjamin 686bb19ba1 Add a unit test for one-sided shutdown.
OpenSSL was actually super-buggy here (though known bugs on our end have been
fixed), but pyOpenSSL was confused and incorrectly documented that callers call
SSL_read after SSL_shutdown to do bidi shutdown, so we should probably support
this. Add a test that it works.

Change-Id: I2b6d012161330aeb4cf894bae3a0b6a55d53c70d
Reviewed-on: https://boringssl-review.googlesource.com/8093
Reviewed-by: Adam Langley <agl@google.com>
2016-06-02 19:24:05 +00:00
Steven Valdez bbd43b5e90 Renaming SSL3_MT_NEWSESSION_TICKET to SSL3_MT_NEW_SESSION_TICKET.
This keeps the naming convention in line with the actual spec.

Change-Id: I34673f78dbc29c1659b4da0e49677ebe9b79636b
Reviewed-on: https://boringssl-review.googlesource.com/8090
Reviewed-by: David Benjamin <davidben@google.com>
2016-06-01 15:58:53 +00:00
Matt Braithwaite db207264ad newhope: refactor and add test vectors.
The test vectors are taken from the reference implementation, modified
to output the results of its random-number generator, and the results of
key generation prior to SHA3.  This allows the interoperability of the
two implementations to be tested somewhat.

To accomplish the testing, this commit creates a new, lower-level API
that leaves the generation of random numbers and all wire encoding and
decoding up to the caller.

Change-Id: Ifae3517696dde4be4a0b7c1998bdefb789bac599
Reviewed-on: https://boringssl-review.googlesource.com/8070
Reviewed-by: Adam Langley <agl@google.com>
2016-05-31 21:57:45 +00:00
David Benjamin 3995a38f3b Print out whether EMS was supported.
Change-Id: I3c5aa418fe767bce883fcdd0a926f922f9f8bbd3
Reviewed-on: https://boringssl-review.googlesource.com/8082
Reviewed-by: Adam Langley <agl@google.com>
2016-05-31 21:11:55 +00:00
David Benjamin 156edfe536 Switch Windows CRYPTO_MUTEX implementation to SRWLOCK.
Now that we no longer support Windows XP, this is available.
Unfortunately, the public header version of CRYPTO_MUTEX means we
still can't easily merge CRYPTO_MUTEX and CRYPTO_STATIC_MUTEX.

BUG=37

Change-Id: If309de3f06e0854c505083b72fd64d1dbb3f4563
Reviewed-on: https://boringssl-review.googlesource.com/8081
Reviewed-by: Adam Langley <agl@google.com>
2016-05-31 21:11:36 +00:00
David Benjamin 29270dea85 Split unlock functions into read/write variants.
Windows SRWLOCK requires you call different functions here. Split
them up in preparation for switching Windows from CRITICAL_SECTION.

BUG=37

Change-Id: I7b5c6a98eab9ae5bb0734b805cfa1ff334918f35
Reviewed-on: https://boringssl-review.googlesource.com/8080
Reviewed-by: Adam Langley <agl@google.com>
2016-05-31 21:09:29 +00:00
Matt Braithwaite 053931e74e CECPQ1: change from named curve to ciphersuite.
This is easier to deploy, and more obvious.  This commit reverts a few
pieces of e25775bc, but keeps most of it.

Change-Id: If8d657a4221c665349c06041bb12fffca1527a2c
Reviewed-on: https://boringssl-review.googlesource.com/8061
Reviewed-by: Adam Langley <agl@google.com>
2016-05-26 19:42:35 +00:00
Adam Langley d09175ffe3 Replace base64 decoding.
This code has caused a long history of problems. This change rewrites it
completely with something that is, hopefully, much simplier and robust
and adds more testing.

Change-Id: Ibeef51f9386afd95d5b73316e451eb3a2d7ec4e0
Reviewed-on: https://boringssl-review.googlesource.com/8033
Reviewed-by: Adam Langley <agl@google.com>
2016-05-26 17:59:10 +00:00
Adam Langley 1cb405d96b Revert "Forbid calling SSL_read, SSL_peek, and SSL_do_handshake post-shutdown."
This reverts commit c7eae5a326. pyOpenSSL
expects to be able to call |SSL_read| after a shutdown and get EOF.

Change-Id: Icc5faa09d644ec29aac99b181dac0db197f283e3
Reviewed-on: https://boringssl-review.googlesource.com/8060
Reviewed-by: Adam Langley <agl@google.com>
2016-05-25 23:23:12 +00:00
Steven Valdez 494650cfcf Adding TLS 1.3 AEAD construction.
The TLS 1.3 spec has an explicit nonce construction for AEADs that
requires xoring the IV and sequence number.

Change-Id: I77145e12f7946ffb35ebeeb9b2947aa51058cbe9
Reviewed-on: https://boringssl-review.googlesource.com/8042
Reviewed-by: Adam Langley <agl@google.com>
2016-05-25 18:04:24 +00:00
Steven Valdez 4f94b1c19f Adding TLS 1.3 constants.
Constants representing TLS 1.3 are added to allow for future work to be
flagged on TLS1_3_VERSION. To prevent BoringSSL from negotiating the
non-existent TLS 1.3 version, it is explicitly disabled using
SSL_OP_NO_TLSv1_3.

Change-Id: Ie5258a916f4c19ef21646c4073d5b4a7974d6f3f
Reviewed-on: https://boringssl-review.googlesource.com/8041
Reviewed-by: Adam Langley <agl@google.com>
2016-05-25 17:41:36 +00:00
Steven Valdez 1eca1d3816 Renaming Channel ID Encrypted Extensions.
This renames the Channel ID EncryptedExtensions message to allow for
compatibility with TLS 1.3 EncryptedExtensions.

Change-Id: I5b67d00d548518045554becb1b7213fba86731f2
Reviewed-on: https://boringssl-review.googlesource.com/8040
Reviewed-by: Adam Langley <agl@google.com>
2016-05-23 20:37:04 +00:00
David Benjamin 2f87112b96 Never expose ssl->bbio in the public API.
OpenSSL's bbio logic is kind of crazy. It would be good to eventually do the
buffering in a better way (notably, bbio is fragile, if not outright broken,
for DTLS). In the meantime, this fixes a number of bugs where the existence of
bbio was leaked in the public API and broke things.

- SSL_get_wbio returned the bbio during the handshake. It must always return
  the BIO the consumer configured. In doing so, internal accesses of
  SSL_get_wbio should be switched to ssl->wbio since those want to see bbio.
  For consistency, do the same with rbio.

- The logic in SSL_set_rfd, etc. (which I doubt is quite right since
  SSL_set_bio's lifetime is unclear) would get confused once wbio got wrapped.
  Those want to compare to SSL_get_wbio.

- If SSL_set_bio was called mid-handshake, bbio would get disconnected and lose
  state. It forgets to reattach the bbio afterwards. Unfortunately, Conscrypt
  does this a lot. It just never ended up calling it at a point where the bbio
  would cause problems.

- Make more explicit the invariant that any bbio's which exist are always
  attached. Simplify a few things as part of that.

Change-Id: Ia02d6bdfb9aeb1e3021a8f82dcbd0629f5c7fb8d
Reviewed-on: https://boringssl-review.googlesource.com/8023
Reviewed-by: Kenny Root <kroot@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-05-23 18:15:03 +00:00
David Benjamin 7e7a82d962 Rename GetConfigPtr to GetTestConfig.
GetConfigPtr was a silly name. GetTestConfig matches the type and GetTestState.

Change-Id: I9998437a7be35dbdaab6e460954acf1b95375de0
Reviewed-on: https://boringssl-review.googlesource.com/8024
Reviewed-by: Adam Langley <agl@google.com>
2016-05-23 15:34:02 +00:00
Adam Langley 7fcfd3b37a Add ISC license to Go files that were missing a license.
Change-Id: I1fe3bed7d5c577748c9f4c3ccd5c1b90fec3d7d7
Reviewed-on: https://boringssl-review.googlesource.com/8032
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-20 18:11:38 +00:00
Steven Valdez ce902a9bcd Generalizing curves to groups in preparation for TLS 1.3.
The 'elliptic_curves' extension is being renamed to 'supported_groups'
in the TLS 1.3 draft, and most of the curve-specific methods are
generalized to groups/group IDs.

Change-Id: Icd1a1cf7365c8a4a64ae601993dc4273802610fb
Reviewed-on: https://boringssl-review.googlesource.com/7955
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-20 17:43:11 +00:00
Steven Valdez f1012b5c31 Fix HKDF leak.
Change-Id: Ia83935420d38ededa699aa7f8011a2e358f6c4d3
Reviewed-on: https://boringssl-review.googlesource.com/8022
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-20 15:42:01 +00:00
David Benjamin 2b1ca80e09 Link back to the main page in documentation.
Also give the main page a title.

Change-Id: I6db588a9454d90a5974de5446d58d709f84d1906
Reviewed-on: https://boringssl-review.googlesource.com/8020
Reviewed-by: Adam Langley <agl@google.com>
2016-05-20 15:36:00 +00:00
Adam Langley 1aa03f0745 Add |EVP_dss1| as an alias for |EVP_sha1| in decrepit.
Change-Id: I51fa744c367d1f0c7044050f99c4992778e649bd
Reviewed-on: https://boringssl-review.googlesource.com/8030
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-20 15:31:52 +00:00
Adam Langley 7cb920b6ac Include crypto.h from pem.h.
open_iscsi assumes that it can get |OPENSSL_malloc| after including only
pem.h and err.h. Since pem.h already includes quite a lot, this change
adds crypto.h to that set so that open_iscsi is happy.

Change-Id: I6dc06c27088ce3ca46c1ab53bb29650033cba267
Reviewed-on: https://boringssl-review.googlesource.com/8031
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-20 15:31:26 +00:00
Steven Valdez 3686584d16 Separating HKDF into HKDFExtract and HKDFExpand.
The key schedule in TLS 1.3 requires a separate Extract and Expand phase
for the cryptographic computations.

Change-Id: Ifdac1237bda5212de5d4f7e8db54e202151d45ec
Reviewed-on: https://boringssl-review.googlesource.com/7983
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-20 15:17:17 +00:00
Matt Braithwaite e25775bcac Elliptic curve + post-quantum key exchange
CECPQ1 is a new key exchange that concatenates the results of an X25519
key agreement and a NEWHOPE key agreement.

Change-Id: Ib919bdc2e1f30f28bf80c4c18f6558017ea386bb
Reviewed-on: https://boringssl-review.googlesource.com/7962
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-19 22:19:14 +00:00
David Benjamin 61d4cdc03d No-op change to kick the bots.
Let's see if the Android bots work!

Change-Id: Ic4a52edcb441c26bc87d776984466e04cff93ae3
2016-05-19 17:55:36 -04:00
nmittler f0322b2abc Use non-deprecated methods on windows.
Use of strdup, close, lseek, read, and write prevent linking
statically againt libcmt.lib.

Change-Id: I04f7876ec0f03f29f000bbcc6b2ccdec844452d2
Reviewed-on: https://boringssl-review.googlesource.com/8010
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-19 20:30:50 +00:00
Matt Braithwaite e09e579603 Rename NEWHOPE functions to offer/accept/finish.
This is consistent with the new convention in ssl_ecdh.c.

Along the way, change newhope_test.c to not iterate 1000 times over each
test.

Change-Id: I7a500f45b838eba8f6df96957891aa8e880ba089
Reviewed-on: https://boringssl-review.googlesource.com/8012
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-19 18:17:48 +00:00
David Benjamin 1147be052c Inherit the parent environment when shelling out to Go.
The recipes need to run with a funny GOROOT and we were clearing the
environment.

BUG=26

Change-Id: If233a16e060533ad3fa6f215ce596456c2d7afa5
Reviewed-on: https://boringssl-review.googlesource.com/7988
Reviewed-by: Adam Langley <agl@google.com>
2016-05-19 18:13:31 +00:00
David Benjamin 3ccf4d6d65 Pull Chromium's android_tools as an android-only dependency.
This will be used by the bots to get adb and the NDK.

BUG=26

Change-Id: Iae07a380c49b4990f0aa7d73c4f0b399924b9784
Reviewed-on: https://boringssl-review.googlesource.com/7986
Reviewed-by: Adam Langley <agl@google.com>
2016-05-19 16:58:13 +00:00
David Benjamin 75021b747f Update Android build instructions.
We now have a copy of android-cmake. Also remove the mention of running cmake
twice. It seems to work fine once?

The API level also got specified twice somehow.

BUG=26

Change-Id: I1331b079a4d8531cd53f7de3605ac318c14b3e26
Reviewed-on: https://boringssl-review.googlesource.com/7985
Reviewed-by: Adam Langley <agl@google.com>
2016-05-19 16:56:25 +00:00
David Benjamin f07ba17942 Check in a copy of android-cmake.
BUG=26

Change-Id: I2f95740afdbc3bdb0676626679a30f1e1cc307d6
Reviewed-on: https://boringssl-review.googlesource.com/7984
Reviewed-by: Adam Langley <agl@google.com>
2016-05-19 16:55:25 +00:00
David Benjamin 00b1069a6b Add an option to pick a different adb binary.
This will let the recipes use the copy pulled from Chromium's android_tools.

BUG=26

Change-Id: Ica6519223b9fb6daef30f3e14c72ef6422de0f6c
Reviewed-on: https://boringssl-review.googlesource.com/7982
Reviewed-by: Adam Langley <agl@google.com>
2016-05-19 16:55:02 +00:00
Tamas Berghammer 5693e42ae4 Fix discovery rule for perl and go for Android
We don't use find_package/find_program on android to find go/perl
because the android toolchain reconfigure the $PATH. The pervious
way of solving this was to let ninja look for go/perl on the $PATH
but this approach prevented us from specifying explicit go/perl
executables what is needed for hermetic build using prebuilts. This
CL changes the Android specific discovery rule to only set
GO_EXECUTABLE and PERL_EXECUTABLE if they are not specified on the
command line or inside the toolchain file.

Change-Id: Ib6ef69707749073f2b79244ebb301502b2a5a34a
Reviewed-on: https://boringssl-review.googlesource.com/8000
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-19 14:46:02 +00:00
David Benjamin ea77107e9a Remove references to non-existent BIO functions.
We don't have any of these.

Change-Id: I8d12284fbbab0ff35ac32d35a5f2eba326ab79f8
Reviewed-on: https://boringssl-review.googlesource.com/7981
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-18 23:41:08 +00:00
Matt Braithwaite c82b70155d Go version of New Hope post-quantum key exchange.
(Code mostly due to agl.)

Change-Id: Iec77396141954e5f8e845cc261eadab77f551f08
Reviewed-on: https://boringssl-review.googlesource.com/7990
Reviewed-by: Adam Langley <agl@google.com>
2016-05-18 22:30:20 +00:00
David Benjamin 54092ffeaa Remove dead checks.
Those checks contradict an assert up in read_app_data. This is part of
shrinking read_bytes further into get_record and its callers until it goes
away. Here, this kind of policy should be controlled by the callers.

Change-Id: If8f9a45b8b95093beab1b3d4abcd31da55c65322
Reviewed-on: https://boringssl-review.googlesource.com/7954
Reviewed-by: Adam Langley <agl@google.com>
2016-05-18 20:52:38 +00:00
David Benjamin fce37b0deb Add a TODO for why init_buf isn't released post-handshake.
There is no good reason why this needs to be this way. Later work should make
this all use a much more appropriate design. In the meantime, leave a note here
so this does not look accidental.

Change-Id: I7599dea7a474f54e26d9ab175b0e3cada99a974d
Reviewed-on: https://boringssl-review.googlesource.com/7951
Reviewed-by: Adam Langley <agl@google.com>
2016-05-18 20:52:19 +00:00
David Benjamin 1d64afda44 Stop reseting init_num everywhere in the handshake loop.
This was needed because ssl3_get_message would get confused if init_num were
not set back to zero when reading the next message. However, ssl3_get_message
now treats init_num only as an output, not an input. (The message sending logic
and the individual handshake states still use it, so we can't get rid of it
altogether yet.)

I've kept the init_num reset at the start and end of the handshake loop alone
for now since that's more about initialization and cleanup. Though I believe
they too do not do anything.

Change-Id: I64bbdd82122498de32364e7edb3b00b166059ecd
Reviewed-on: https://boringssl-review.googlesource.com/7950
Reviewed-by: Adam Langley <agl@google.com>
2016-05-18 20:52:04 +00:00
David Benjamin 1e6d6df943 Remove state parameters to ssl3_get_message.
They're completely unused now. The handshake message reassembly logic should
not depend on the state machine. This should partially free it up (ugly as it
is) to be shared with a future TLS 1.3 implementation while, in parallel, it
and the layers below, get reworked. This also cuts down on the number of states
significantly.

Partially because I expect we'd want to get ssl_hash_message_t out of there
too. Having it in common code is fine, but it needs to be in the (supposed to
be) protocol-agnostic handshake state machine, not the protocol-specific
handshake message layer.

Change-Id: I12f9dc57bf433ceead0591106ab165d352ef6ee4
Reviewed-on: https://boringssl-review.googlesource.com/7949
Reviewed-by: Adam Langley <agl@google.com>
2016-05-18 20:51:48 +00:00
David Benjamin a6338be3fa Simplify ssl3_get_message.
Rather than this confusing coordination with the handshake state machine and
init_num changing meaning partway through, use the length field already in
BUF_MEM. Like the new record layer parsing, is no need to keep track of whether
we are reading the header or the body. Simply keep extending the handshake
message until it's far enough along.

ssl3_get_message still needs tons of work, but this allows us to disentangle it
from the handshake state.

Change-Id: Ic2b3e7cfe6152a7e28a04980317d3c7c396d9b08
Reviewed-on: https://boringssl-review.googlesource.com/7948
Reviewed-by: Adam Langley <agl@google.com>
2016-05-18 20:50:57 +00:00
David Benjamin 1f9329aaf5 Add BUF_MEM_reserve.
BUF_MEM is actually a rather silly API for the SSL stack. There's separate
length and max fields, but init_buf effectively treats length as max and max as
nothing.

We possibly don't want to be using it long-term anyway (if nothing else, the
char*/uint8_t* thing is irritating), but in the meantime, it'll be easier to
separately fix up get_message's book-keeping and state tracking from where the
handshake gets its messages from.

Change-Id: I9e56ea008173991edc8312ec707505ead410a9ee
Reviewed-on: https://boringssl-review.googlesource.com/7947
Reviewed-by: Adam Langley <agl@google.com>
2016-05-18 19:09:06 +00:00
David Benjamin 4d559617cd Unflake Unclean-Shutdown-Alert on Windows.
On Windows, if we write to our socket and then close it, the peer sometimes
doesn't get all the data. This was working for our shimShutsDown tests because
we send close_notify in parallel with the peer and sendAlert(alertCloseNotify)
did not internally return an error.

For convenience, sendAlert returns a local error for non-close_notify alerts.
Suppress that error to avoid the race condition. This makes it behave like the
other shimShutsDown tests.

Change-Id: Iad256e3ea5223285793991e2eba9c7d61f2e3ddf
Reviewed-on: https://boringssl-review.googlesource.com/7980
Reviewed-by: Adam Langley <agl@google.com>
2016-05-18 18:59:38 +00:00
Matt Braithwaite f4ce8e5324 Refactor ECDH key exchange to make it asymmetrical
Previously, SSL_ECDH_METHOD consisted of two methods: one to produce a
public key to be sent to the peer, and another to produce the shared key
upon receipt of the peer's message.

This API does not work for NEWHOPE, because the client-to-server message
cannot be produced until the server's message has been received by the
client.

Solve this by introducing a new method which consumes data from the
server key exchange message and produces data for the client key
exchange message.

Change-Id: I1ed5a2bf198ca2d2ddb6d577888c1fa2008ef99a
Reviewed-on: https://boringssl-review.googlesource.com/7961
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-18 18:09:26 +00:00
David Benjamin 68a533c0ef Fix line-number counting in doc.go.
There's an off-by-one when skipping blank lines. The initial logic also has an
off-by-one but since it starts lineNo 0-based and then switches to 1-based, it
cancels out.

The decl error line number also was not of where the decl began.

Change-Id: I58fd157dad3276cb9de52ac48ff8c7c73e40f337
Reviewed-on: https://boringssl-review.googlesource.com/7959
Reviewed-by: Adam Langley <agl@google.com>
2016-05-17 21:57:16 +00:00
David Benjamin 7f6706ce64 MSVC doesn't like C bitfields.
Change-Id: I88a415e3dd7ac9ea2fa83ca3e4d835efefa7fcc6
Reviewed-on: https://boringssl-review.googlesource.com/7970
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-17 21:50:45 +00:00
David Benjamin 47f5a1feca Allow documentation comments to begin with A/An.
This aligns with Go style.

Change-Id: I773c6a2e8ddd8d40a8480efae86736c4b338d203
Reviewed-on: https://boringssl-review.googlesource.com/7958
Reviewed-by: Adam Langley <agl@google.com>
2016-05-17 21:40:47 +00:00
David Benjamin c7eae5a326 Forbid calling SSL_read, SSL_peek, and SSL_do_handshake post-shutdown.
This explicitly forbids an API pattern which formerly kind of worked, but was
extremely buggy (see preceding commits). Depending on how one interprets
close_notify and our API, one might wish to call SSL_shutdown only once
(morally shutdown(SHUT_WR)) and then SSL_read until EOF.

However, this exposes additional confusing states where we might try to send an
alert post-SHUT_WR, etc. Early commits made us more robust here (whether one is
allowed to touch the SSL* after an operattion failed because it read an alert
is... unclear), so we could support it if we wanted to, but this doesn't seem
worth the additional statespace. See if we can get away with not allowing it.

Change-Id: Ie7a7e5520b464360b1e6316c34ec9854b571782f
Reviewed-on: https://boringssl-review.googlesource.com/7433
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-17 21:28:40 +00:00
David Benjamin ea65e100c7 Condition the read_close_notify check on type, not shutdown state.
The logic to drop records really should be in the caller. Unless
ssl3_read_bytes is broken apart, condition on the type field which is more
robust.

If we manage to call, say, SSL_read after SSL_shutdown completes at 0 (instead
of 1), this logic can incorrectly cause unknown record types to be dropped.

Change-Id: Iab90e5d9190fcccbf6ff55e17079a2704ed99901
Reviewed-on: https://boringssl-review.googlesource.com/7953
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-17 21:27:43 +00:00
David Benjamin fa214e4a18 Tidy up shutdown state.
The existing logic gets confused in a number of cases around close_notify vs.
fatal alert. SSL_shutdown, while still pushing to the error queue, will fail to
notice alerts. We also get confused if we try to send a fatal alert when we've
already sent something else.

Change-Id: I9b1d217fbf1ee8a9c59efbebba60165b7de9689e
Reviewed-on: https://boringssl-review.googlesource.com/7952
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-17 21:27:12 +00:00
David Benjamin 8f73135485 Consolidate SSL_RECEIVED_SHUTDOWN checks.
SSL_RECEIVED_SHUTDOWN checks in the record layer happen in two different
places. Some operations (but not all) check it, and so does read_bytes. Move it
to get_record.

This check should be at a low-level since it is otherwise duplicated in every
operation. It is also a signal which originates from around the peer's record
layer, so it makes sense to check it near the same code. (This one's in
get_record which is technically lower-level than read_bytes, but we're trying
to get rid of read_bytes. They're very coupled functions.)

Also, if we've seen a fatal alert, replay an error, not an EOF.

Change-Id: Idec35c5068ddabe5b1a9145016d8f945da2421cf
Reviewed-on: https://boringssl-review.googlesource.com/7436
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-17 21:02:19 +00:00
Adam Langley f448c60903 Update INCORPORATING.md to clarify one point.
In practice it seems that it's not clear that consumers of BoringSSL
generally check in the generated files.

Change-Id: Iaa03aa62139bbcf3e7e7f68662073854954b835f
Reviewed-on: https://boringssl-review.googlesource.com/7956
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-17 19:39:55 +00:00
Adam Langley 4fac8d0eae Add CRYPTO_has_asm.
This function will return whether BoringSSL was built with
OPENSSL_NO_ASM. This will allow us to write a test in our internal
codebase which asserts that normal builds should always have assembly
code included.

Change-Id: Ib226bf63199022f0039d590edd50c0cc823927b9
Reviewed-on: https://boringssl-review.googlesource.com/7960
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-17 19:03:31 +00:00
David Benjamin c032dfa27e Client auth is only legal in certificate-based ciphers.
OpenSSL used to only forbid it on the server in plain PSK and allow it on the
client. Enforce it properly on both sides. My read of the rule in RFC 5246 ("A
non-anonymous server can optionally request a certificate") and in RFC 4279
("The Certificate and CertificateRequest payloads are omitted from the
response.") is that client auth happens iff we're certificate-based.

The line in RFC 4279 is under the plain PSK section, but that doesn't make a
whole lot of sense and there is only one diagram. PSK already authenticates
both sides. I think the most plausible interpretation is that this is for
certificate-based ciphers.

Change-Id: If195232c83f21e011e25318178bb45186de707e6
Reviewed-on: https://boringssl-review.googlesource.com/7942
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-13 20:07:16 +00:00
David Benjamin 060cfb0911 Simplify handshake message size limits.
A handshake message can go up to 2^24 bytes = 16MB which is a little large for
the peer to force us to buffer. Accordingly, we bound the size of a
handshake message.

Rather than have a global limit, the existing logic uses a different limit at
each state in the handshake state machine and, for certificates, allows
configuring the maximum certificate size. This is nice in that we engage larger
limits iff the relevant state is reachable from the handshake. Servers without
client auth get a tighter limit "for free".

However, this doesn't work for DTLS due to out-of-order messages and we use a
simpler scheme for DTLS. This scheme also is tricky on optional messages and
makes the handshake <-> message layer communication complex.

Apart from an ignored 20,000 byte limit on ServerHello, the largest
non-certificate limit is the common 16k limit on ClientHello. So this
complexity wasn't buying us anything. Unify everything on the DTLS scheme
except, so as not to regress bounds on client-auth-less servers, also correctly
check for whether client auth is configured. The value of 16k was chosen based
on this value.

(The 20,000 byte ServerHello limit makes no sense. We can easily bound the
ServerHello because servers may not send extensions we don't implement. But it
gets overshadowed by the certificate anyway.)

Change-Id: I00309b16d809a3c2a1543f99fd29c4163e3add81
Reviewed-on: https://boringssl-review.googlesource.com/7941
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-13 20:06:24 +00:00
Brian Smith 4e7a1ff055 Remove unuseful comments in |BN_mod_exp|.
The performance measurements seem to be very out-of-date. Also, the
idea for optimizing the case of an even modulus is interesting, but it
isn't useful because we never use an even modulus.

Change-Id: I012eb37638cda3c63db0e390c8c728f65b949e54
Reviewed-on: https://boringssl-review.googlesource.com/7733
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-13 19:10:47 +00:00
Brian Smith 448fa42779 Deprecate |BN_mod_exp2_mont| and simplify its implementation.
This function is only really useful for DSA signature verification,
which is something that isn't performance-sensitive. Replace its
optimized implementation with a naïve implementation that's much
simpler.

Note that it would be simpler to use |BN_mod_mul| in the new
implementation; |BN_mod_mul_montgomery| is used instead only to be
consistent with other work being done to replace uses of non-Montgomery
modular reduction with Montgomery modular reduction.

Change-Id: If587d463b73dd997acfc5b7ada955398c99cc342
Reviewed-on: https://boringssl-review.googlesource.com/7732
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-13 19:10:18 +00:00
David Benjamin ada97998f2 Fix stack macro const-ness.
sk_FOO_num may be called on const stacks. Given that was wrong, I suspect no
one ever uses a const STACK_OF(T)...

Other macros were correctly const, but were casting the constness a way (only
to have it come back again).

Also remove the extra newline after a group. It seems depending on which
version of clang-format was being used, we'd either lose or keep the extra
newline. The current file doesn't have them, so settle on that.

Change-Id: I19de6bc85b0a043d39c05ee3490321e9f0adec60
Reviewed-on: https://boringssl-review.googlesource.com/7946
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-13 18:24:57 +00:00
David Benjamin c6cc6e76a6 Make kSRTPProfiles static.
It's only used in one file.

Change-Id: I5d60cbc02799b22317f5f7593faf25eb8eea0a24
Reviewed-on: https://boringssl-review.googlesource.com/7943
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-13 14:12:22 +00:00
David Benjamin ef2dc61edd Remove invalid comment for alert_dispatch.
The array is of size two for the level and description, not because we allow
two alerts outstanding; we don't.

Change-Id: I25e42c059ce977a947397a3dc83e9684bc8f0595
Reviewed-on: https://boringssl-review.googlesource.com/7940
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-13 13:56:38 +00:00
David Benjamin 8de8b3d23c Revise run_android_tests.go for use in recipes.
Allow running only one of the test suites. The recipe expects these happen in
two separate steps (it wants only one JSON results file per "step"). Also add
an option to extract the results file.

BUG=26

Change-Id: I0cda19bd9643b66f40a30bc8410a357da33baacc
Reviewed-on: https://boringssl-review.googlesource.com/7945
Reviewed-by: Adam Langley <agl@google.com>
2016-05-13 13:55:41 +00:00
David Benjamin 641f42b1a2 Make i2d_X509_AUX work if *pp = NULL.
When *pp is NULL, don't write garbage, return an unexpected pointer
or leak memory on error.

(Imported from upstream's 36c37944909496a123e2656ad1f651769a7cc72f.)

This calling convention...

Change-Id: Ic733092cfb942a3e1d3ceda6797222901ad55bef
Reviewed-on: https://boringssl-review.googlesource.com/7944
Reviewed-by: Adam Langley <agl@google.com>
2016-05-13 13:53:48 +00:00
David Benjamin 80d1b35520 Add a test for SCTs sent on resume.
The specification, sadly, did not say that servers MUST NOT send it, only that
they are "not expected to" do anything with the client extension. Accordingly,
we decided to tolerate this. Add a test for this so that we check this
behavior.

This test also ensures that the original session's value for it carries over.

Change-Id: I38c738f218a09367c9d8d1b0c4d68ab5cbec730e
Reviewed-on: https://boringssl-review.googlesource.com/7860
Reviewed-by: Adam Langley <agl@google.com>
2016-05-13 13:45:26 +00:00
Brian Smith e31d103a0a Deprecate |BN_mod_exp_mont_word| and simplify its implementation.
|BN_mod_exp_mont_word| is only useful when the base is a single word
in length and timing side channel protection of the exponent is not
needed. That's never the case in real life.

Keep the function in the API, but removes its single-word-base
optimized implementation with a call to |BN_mod_exp_mont|.

Change-Id: Ic25f6d4f187210b681c6ee6b87038b64a5744958
Reviewed-on: https://boringssl-review.googlesource.com/7731
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-11 23:22:32 +00:00
Taylor Brandstetter 376a0fed24 Adding a method to change the initial DTLS retransmission timer value.
This allows an application to override the default of 1 second, which
is what's instructed in RFC 6347 but is not an absolute requirement.

Change-Id: I0bbb16e31990fbcab44a29325b6ec7757d5789e5
Reviewed-on: https://boringssl-review.googlesource.com/7930
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-11 22:36:26 +00:00
Brian Smith 0e01eb534c Call |BN_mod_exp_mont_consttime| in crypto/dh.
|BN_mod_exp_mont| will forward to |BN_mod_exp_mont_consttime|, so this
is a no-op semantically. However, this allows the linker to drop the
implementation of |BN_mod_exp_mont| even when the DH code is in use.

Change-Id: I0cb8b260224ed661ede74923bd134acb164459c1
Reviewed-on: https://boringssl-review.googlesource.com/7730
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-11 22:34:19 +00:00
David Benjamin d229433d75 Free any existing SRTP connection profile.
When setting a new SRTP connection profile using
SSL_CTX_set_tlsext_use_srtp() or SSL_set_tlsext_use_srtp() we should
free any existing profile first to avoid a memory leak.

(Imported from upstream's fbdf0299dc98bc611d854c0a62c6ab1810d856fc.)

Change-Id: I738e711f1c23ed4a8ac97486d94c08cc0db7aea7
Reviewed-on: https://boringssl-review.googlesource.com/7910
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-09 19:36:54 +00:00
David Benjamin 3473315415 Reimplement PKCS #3 DH parameter parsing with crypto/bytestring.
Also add a test.

This is the last of the openssl/asn1.h includes from the directories that are
to be kept in the core libcrypto library. (What remains is to finish sorting
out the crypto/obj stuff. We'll also want to retain a decoupled version of the
PKCS#12 stuff.)

Functions that need to be audited for reuse:
i2d_DHparams

BUG=54

Change-Id: Ibef030a98d3a93ae26e8e56869f14858ec75601b
Reviewed-on: https://boringssl-review.googlesource.com/7900
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-09 19:36:41 +00:00
David Benjamin e72df93461 Add a README.md for ssl/test.
The SSL tests are fairly different from most test suites. Add some high-level
documentation so people know where to start.

Change-Id: Ie5ea108883dca82675571a3025b3fbc4b9d66da9
Reviewed-on: https://boringssl-review.googlesource.com/7890
Reviewed-by: Adam Langley <agl@google.com>
2016-05-06 17:40:28 +00:00
David Benjamin e9a3642126 Don't reset ssl->shutdown in the state machine.
This is particularly questionable with ClientHello encompassing several states.
ssl->shutdown is already initialized to zero and further reset in
SSL_set_{connect,accept}_state. At any other state, if it manages to not be a
no-op, it will erase a close_notify we have sent or received, neither of which
is okay. (I don't think this is possible, but I'm not positive.)

This dates to the initial commit in OpenSSL, so git is not enlightening. The
state machine logic historically reset many fields it had no reason to reset,
so this is likely more of that.

Change-Id: Ie872316701720cb8ef2cfcb67b7f07a9fea3620f
Reviewed-on: https://boringssl-review.googlesource.com/7874
Reviewed-by: Adam Langley <agl@google.com>
2016-05-06 17:40:17 +00:00
David Benjamin b095f0f0ca Remove the push argument to ssl_init_wbio_buffer.
Having bbio be tri-state (not allocated, allocated but not active, and
allocated and active) is confusing.

The extra state is only used in the client handshake, where ClientHello is
special-cased to not go through the buffer while everything else is. This dates
to OpenSSL's initial commit and doesn't seem to do much. I do not believe it
can affect renego as the buffer only affects writes; although OpenSSL accepted
interleave on read (though this logic predates it slightly), it never sent
application data while it believed a handshake was active. The handshake would
always be driven to completion first.

My guess is this was to save a copy since the ClientHello is a one-message
flight so it wouldn't need to be buffered? This is probably not worth the extra
variation in the state. (Especially with the DTLS state machine going through
ClientHello twice and pushing the BIO in between the two. Though I suspect that
was a mistake in itself. If the optimization guess is correct, there was no
need to do that.)

Change-Id: I6726f866e16ee7213cab0c3e6abb133981444d47
Reviewed-on: https://boringssl-review.googlesource.com/7873
Reviewed-by: Adam Langley <agl@google.com>
2016-05-06 17:39:48 +00:00
David Benjamin 2730955e74 Check BIO_flush return value.
That we're ignoring the return value is clearly wrong when
dtls1_retransmit_message has other code that doesn't ignore it, by way of
dtls1_do_handshake_write.

Change-Id: Ie3f8c0defdf1f5e709d67af4ca6fa4f0d83c76c9
Reviewed-on: https://boringssl-review.googlesource.com/7872
Reviewed-by: Adam Langley <agl@google.com>
2016-05-06 17:38:33 +00:00
David Benjamin 30152fdfc1 Always buffer DTLS retransmits.
The DTLS bbio logic is rather problematic, but this shouldn't make things
worse. In the in-handshake case, the new code merges the per-message
(unchecked) BIO_flush calls into one call at the end but otherwise the BIO is
treated as is. Otherwise any behavior around non-block writes should be
preserved.

In the post-handshake case, we now install the buffer when we didn't
previously. On write error, the buffer will have garbage in it, but it will be
discarded, so that will preserve any existing retry behavior. (Arguably the
existing retry behavior is a bug, but that's another matter.)

Add a test for all this, otherwise it is sure to regress. Testing for
record-packing is a little fuzzy, but we can assert ChangeCipherSpec always
shares a record with something.

BUG=57

Change-Id: I8603f20811d502c71ded2943b0e72a8bdc4e46f2
Reviewed-on: https://boringssl-review.googlesource.com/7871
Reviewed-by: Adam Langley <agl@google.com>
2016-05-06 17:37:11 +00:00
David Benjamin 9d908ba519 Add BORINGSSL_API_VERSION.
The BORINGSSL_YYYYMM #defines have served well to coordinate short-term skews
in BoringSSL's public API, but some consumers (notably wpa_supplicant in
Android) wish to build against multiple versions for an extended period of
time. Consumers should not do this unless there is no alternative, but to
accommodate this, start a BORINGSSL_API_VERSION counter. In future, instead of
BORINGSSL_YYYYMM #defines, we'll simply increment the number.

This is specifically called an "API version" rather than a plain "version" as
this number does not denote any particular point in development or stability.
It purely counts how many times we found it convenient to let the preprocessor
observe a public API change up to now.

Change-Id: I39f9740ae8e793cef4c2b5fb5707b9763b3e55ce
Reviewed-on: https://boringssl-review.googlesource.com/7870
Reviewed-by: Adam Langley <agl@google.com>
2016-05-05 23:06:09 +00:00
Brian Smith 598e55a795 Do RSA blinding unless |e| is NULL and specifically requested not to.
Change-Id: I189db990df2a3cbf68f820a8f9f16142ccd7070f
Reviewed-on: https://boringssl-review.googlesource.com/7595
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-04 23:14:08 +00:00
Brian Smith 86080c336f Verify RSA private key operation regardless of whether CRT is used.
Previously, the verification was only done when using the CRT method,
as the CRT method has been shown to be extremely sensitive to fault
attacks. However, there's no reason to avoid doing the verification
when the non-CRT method is used (performance-sensitive applications
should always be using the CRT-capable keys).

Previously, when we detected a fault (attack) through this verification,
libcrypto would fall back to the non-CRT method and assume that the
non-CRT method would give a correct result, despite having just
detecting corruption that is likely from an attack. Instead, just give
up, like NSS does.

Previously, the code tried to handle the case where the input was not
reduced mod rsa->n. This is (was) not possible, so avoid trying to
handle that. This simplifies the equality check and lets us use
|CRYPTO_memcmp|.

Change-Id: I78d1e55520a1c8c280cae2b7256e12ff6290507d
Reviewed-on: https://boringssl-review.googlesource.com/7582
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-04 22:58:17 +00:00
Adam Langley 8107e92a1a Add a comment with an SMT verification of the Barrett reductions.
Change-Id: I32dc13b16733fc09e53e3891ca68f51df6c1624c
Reviewed-on: https://boringssl-review.googlesource.com/7850
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-04 17:51:10 +00:00
David Benjamin f0bba61663 Fix ASN1_INTEGER handling.
Only treat an ASN1_ANY type as an integer if it has the V_ASN1_INTEGER
tag: V_ASN1_NEG_INTEGER is an internal only value which is never used
for on the wire encoding.

(Imported from upstream's d4b25980020821d4685752ecb9105c0902109ab5.)

This is redundant with our fb2c6f8c85 which I
think is a much better fix (having two notions of "type" depending on whether
we're in an ASN1_TYPE or an ASN1_STRING is fragile), so I think we should keep
our restriction too. Still, this is also worth doing.

Change-Id: I6ea54aae7b517a59c6e563d8c993d0ee22e25bee
Reviewed-on: https://boringssl-review.googlesource.com/7848
Reviewed-by: Adam Langley <agl@google.com>
2016-05-03 16:58:51 +00:00
David Benjamin de2cf273d7 Avoid theoretical overflows in EVP_EncodeUpdate.
See also upstream's 172c6e1e14defe7d49d62f5fc9ea6a79b225424f, but note our
values have different types. In particular, because we put in_len in a size_t
and C implicitly requires that all valid buffers' lengths fit in a ptrdiff_t
(signed), the overflow was impossible, assuming EVP_ENCODE_CTX::length is
untouched externally.

More importantly, this function is stuck taking an int output and has no return
value, so the only plausible contract is the caller is responsible for ensuring
the length fits anyway. Indeed, callers all call EVP_EncodeUpdate in bounded
chunks, so upstream's analysis is off.

Anyway, in theory that logic could locally overflow, so tweak it slightly. Tidy
up some of the variable names while I'm here.

Change-Id: Ifa78707cc26c11e0d67019918a028531b3d6738c
Reviewed-on: https://boringssl-review.googlesource.com/7847
Reviewed-by: Adam Langley <agl@google.com>
2016-05-03 16:45:42 +00:00
David Benjamin e31e0123ea Add size limit to X509_NAME structure.
This adds an explicit limit to the size of an X509_NAME structure. Some
part of OpenSSL (e.g. TLS) already effectively limit the size due to
restrictions on certificate size.

See also upstream's 65cb92f4da37a3895437f0c9940ee0bcf9f28c8a, although this is
different from upstream's. Upstream's version bounds both the X509_NAME *and*
any data after it in the immediately containing structure. While adding a bound
on all of crypto/asn1 is almost certainly a good idea (will look into that for
a follow-up), it seems bizarre and unnecessary to have X509_NAME affect its
parent.

Change-Id: Ica2136bcd1455d7c501ccc6ef2a19bc5ed042501
Reviewed-on: https://boringssl-review.googlesource.com/7846
Reviewed-by: Adam Langley <agl@google.com>
2016-05-03 16:43:52 +00:00
David Benjamin 204dea8dae Fix encrypt overflow
An overflow can occur in the EVP_EncryptUpdate function. If an attacker is
able to supply very large amounts of input data after a previous call to
EVP_EncryptUpdate with a partial block then a length check can overflow
resulting in a heap corruption.

Following an analysis of all OpenSSL internal usage of the
EVP_EncryptUpdate function all usage is one of two forms.

The first form is like this:
EVP_EncryptInit()
EVP_EncryptUpdate()

i.e. where the EVP_EncryptUpdate() call is known to be the first called
function after an EVP_EncryptInit(), and therefore that specific call
must be safe.

The second form is where the length passed to EVP_EncryptUpdate() can be seen
from the code to be some small value and therefore there is no possibility of
an overflow. [BoringSSL: We also have code that calls EVP_CIPHER functions by
way of the TLS/SSL3 "AEADs". However, there we know the inputs are bounded by
2^16.]

Since all instances are one of these two forms, I believe that there can
be no overflows in internal code due to this problem.

It should be noted that EVP_DecryptUpdate() can call EVP_EncryptUpdate()
in certain code paths. Also EVP_CipherUpdate() is a synonym for
EVP_EncryptUpdate(). Therefore I have checked all instances of these
calls too, and came to the same conclusion, i.e. there are no instances
in internal usage where an overflow could occur.

This could still represent a security issue for end user code that calls
this function directly.

CVE-2016-2106

Issue reported by Guido Vranken.

(Imported from upstream's 3ab937bc440371fbbe74318ce494ba95021f850a.)

Change-Id: Iabde896555c39899c7f0f6baf7a163a7b3c2f3d6
Reviewed-on: https://boringssl-review.googlesource.com/7845
Reviewed-by: Adam Langley <agl@google.com>
2016-05-03 16:43:12 +00:00
David Benjamin a43fd90c5d Sync with upstream on i2d_X509_AUX.
Upstream decided to reset *pp on error and to later fix up the other i2d
functions to behave similarly. See upstream's
c5e603ee182b40ede7713c6e229c15a8f3fdb58a.

Change-Id: I01f82b578464060d0f2be5460fe4c1b969124c8e
Reviewed-on: https://boringssl-review.googlesource.com/7844
Reviewed-by: Adam Langley <agl@google.com>
2016-05-03 16:37:19 +00:00
David Benjamin eb3257211e Don't free ret->data if malloc fails.
Issue reported by Guido Vranken.

(Imported from upstream's 64eaf6c928f4066d62aa86f805796ef05bd0b1cc.)

Change-Id: I99793abb4e1b5da5b70468b207ec03013fff674a
Reviewed-on: https://boringssl-review.googlesource.com/7843
Reviewed-by: Adam Langley <agl@google.com>
2016-05-03 16:36:04 +00:00
David Benjamin 52a3bf2835 Add checks to X509_NAME_oneline()
Sanity check field lengths and sums to avoid potential overflows and reject
excessively large X509_NAME structures.

Issue reported by Guido Vranken.

(Imported from upstream's 9b08619cb45e75541809b1154c90e1a00450e537.)

Change-Id: Ib2e1e7cd086f9c3f0d689d61947f8ec3e9220049
Reviewed-on: https://boringssl-review.googlesource.com/7842
Reviewed-by: Adam Langley <agl@google.com>
2016-05-03 16:34:59 +00:00
David Benjamin ddc69230f3 Sanity check buffer length.
Reject zero length buffers passed to X509_NAME_oneline().

Issue reported by Guido Vranken.

(Imported from upstream's 66e731ab09f2c652d0e179df3df10d069b407604.)

Tweaked slightly to use <= 0 instead of == 0 since the length is signed.

Change-Id: I5ee54d77170845e4699fda7df5e94538c8e55ed9
Reviewed-on: https://boringssl-review.googlesource.com/7841
Reviewed-by: Adam Langley <agl@google.com>
2016-05-03 16:30:41 +00:00
David Benjamin d230a0c890 Reject inappropriate private key encryption ciphers.
The traditional private key encryption algorithm doesn't function
properly if the IV length of the cipher is zero. These ciphers
(e.g. ECB mode) are not suitable for private key encryption
anyway.

(Imported from upstream's 4436299296cc10c6d6611b066b4b73dc0bdae1a6.)

Change-Id: I218c9c1d11274ef11b7c0cfce380521efa415215
Reviewed-on: https://boringssl-review.googlesource.com/7840
Reviewed-by: Adam Langley <agl@google.com>
2016-05-03 16:30:08 +00:00
Adam Langley b83c680d03 Add |CRYPTO_is_confidential_build|.
In the past we have needed the ability to deploy security fixes to our
frontend systems without leaking them in source code or in published
binaries.

This change adds a function that provides some infrastructure for
supporting this in BoringSSL while meeting our internal build needs. We
do not currently have any specific patch that requires this—this is
purely preparation.

Change-Id: I5c64839e86db4e5ea7419a38106d8f88b8e5987e
Reviewed-on: https://boringssl-review.googlesource.com/7849
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-03 16:24:50 +00:00
David Benjamin 8368050fa9 Clean up ssl_get_compatible_server_ciphers.
The logic is a little hairy, partly because we used to support multiple
certificate slots.

Change-Id: Iee8503e61f5e0e91b7bcb15f526e9ef7cc7ad860
Reviewed-on: https://boringssl-review.googlesource.com/7823
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-02 19:55:32 +00:00
David Benjamin 7acd6bc07a Start assuming MSVC 2015.
BUG=43

Change-Id: I46ad1ca62b8921a03fae51f5d7bbe1c68fc0b170
Reviewed-on: https://boringssl-review.googlesource.com/7821
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-02 19:46:25 +00:00
David Benjamin 8861daa5a9 Fix vs_toolchain.py, possibly.
Sync a few changes with the upstream one, notably get_toolchain_if_necessary.py
needs GYP_MSVS_VERSION set. Also pull the variables that change up to the top.
This diverges a bit more from the upstream one, but we're already heavily
diverged. If we ever need to support two concurrent toolchains, I'll bring us
closer to parity.

Change-Id: I6db7fbaccd5dddd92ad2deee15bd6dd3e28841f7
Reviewed-on: https://boringssl-review.googlesource.com/7830
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-02 19:25:53 +00:00
David Benjamin bbe6af0e2a Bump requirements to MSVC 2015.
Track the Chromium requirements. This makes our bots build with 2015 instead of
2013.

BUG=43

Change-Id: Id5329900a5d1d5fae4b5b22299ed47bc1b947dd8
Reviewed-on: https://boringssl-review.googlesource.com/7820
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-02 18:59:02 +00:00
David Benjamin 9e7efdb008 Update the various pinned revisions in util/bot.
See util/bot/UPDATING for where they come from.

Change-Id: Ib2eae6efc737dd8c4e5fb001fd4b478102e0ad6a
Reviewed-on: https://boringssl-review.googlesource.com/7822
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-05-02 17:54:33 +00:00
David Benjamin d18cb77864 Fix d2i_X509_AUX.
The logic to reset *pp doesn't actually work if pp is NULL. (It also doesn't
work if *pp is NULL, but that didn't work before either.) Don't bother
resetting it. This is consistent with the template-based i2d functions which do
not appear to leave *pp alone on error.

Will send this upstream.

Change-Id: I9fb5753e5d36fc1d490535720b8aa6116de69a70
Reviewed-on: https://boringssl-review.googlesource.com/7812
Reviewed-by: Adam Langley <agl@google.com>
2016-04-29 20:26:52 +00:00
David Benjamin 176dbf04b7 Check for malloc failure in r2i_certpol.
See upstream's 34b9acbd3f81b46967f692c0af49020c8c405746.

Change-Id: I88d5b3cfbbe87e883323a9e6e1bf85227ed9576e
Reviewed-on: https://boringssl-review.googlesource.com/7811
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-29 16:22:05 +00:00
David Benjamin 3bb5a77205 Fix memory leak on error in BN_mpi2bn.
See also upstream's 91fb42ddbef7a88640d1a0f853c941c20df07de7, though that has a
bug if |out| was non-NULL on entry. (I'll send them a patch.)

Change-Id: I807f23007b89063c23e02dac11c4ffb41f847fdf
Reviewed-on: https://boringssl-review.googlesource.com/7810
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-29 16:20:14 +00:00
Nick Harper 6f621bd8f7 Merge documentation from chromium's net/der into cbs.c
Change-Id: Icfd959a168e3fce423b10dd0dcb1312ec03f0623
Reviewed-on: https://boringssl-review.googlesource.com/7800
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-28 19:39:40 +00:00
David Benjamin 992c20aedc Another OPENSSL_NO_THREADS build fix.
GCC gets unhappy if we don't initialize the padding.

Change-Id: I084ffee1717d9025dcb10d8f32de0da2339c7f01
Reviewed-on: https://boringssl-review.googlesource.com/7797
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-28 17:32:42 +00:00
David Benjamin 0a63b96535 Make CRYPTO_is_NEON_capable aware of the buggy CPU.
If we're to allow the buggy CPU workaround to fire when __ARM_NEON__ is set,
CRYPTO_is_NEON_capable also needs to be aware of it. Also add an API to export
this value out of BoringSSL, so we can get some metrics on how prevalent this
chip is.

BUG=chromium:606629

Change-Id: I97d65a47a6130689098b32ce45a8c57c468aa405
Reviewed-on: https://boringssl-review.googlesource.com/7796
Reviewed-by: Adam Langley <agl@google.com>
2016-04-28 16:42:21 +00:00
David Benjamin b3be1cf97d Add a 'configs_exclude' option to the generated GN 'create_tests' template.
Chromium uses GN's default configs feature which makes all targets default to a
set of configs. It then expects third_party code to take one of them
(chromium_code) out and put in a different one (no_chromium_code).

Because of that, we need a way to tell the template to emit -= lines. Add a
separate option for that.

(It may be worth making us clean against the chromium_code config rather than
the no_chromium_code one, but I'll explore that separately in case making the C
code clean ends up being a rabbithole.)

BUG=chromium:607294

Change-Id: I2aa179665ab17439cc123fc86a7af9690cd4bcd6
Reviewed-on: https://boringssl-review.googlesource.com/7795
Reviewed-by: Adam Langley <agl@google.com>
2016-04-28 14:58:01 +00:00
David Benjamin 2b4820bd52 Don't set a default armcap state in dynamic armcap modes.
The getauxval (and friends) code would be filling that in anyway. The default
only serves to enable NEON even if the OS is old enough to be missing getauxval
(and everything else).

Notably, this unbreaks the has_buggy_neon code when __ARM_NEON__ is set, as is
the case in Chrome for Android, as of M50.  Before, the default
OPENSSL_armcap_P value was getting in the way.

Arguably, this doesn't make a whole lot of sense. We're saying we'll let the
CPU run compiler-generated NEON code, but not our hand-crafted stuff. But, so
far, we only have evidence of the hand-written NEON tickling the bug and not
the compiler-generated stuff, so avoid the unintentional regression. (Naively,
I would expect the hand-crafted NEON is better at making full use of the
pipeline and is thus more likely to tickle the CPU bug.)

This is not the fix for M50, as in the associated Chromium bug, but it will fix
master and M51. M50 will instead want to revert
https://codereview.chromium.org/1730823002.

BUG=chromium:606629

Change-Id: I394f97fea2f09891dd8fa30e0ec6fc6b1adfab7a
Reviewed-on: https://boringssl-review.googlesource.com/7794
Reviewed-by: Adam Langley <agl@google.com>
2016-04-27 23:59:24 +00:00
Matt Braithwaite 9478f32175 newhope: use less stack to compute client key
Change-Id: Idf500545317242c8855e67b897975e54969fea10
Reviewed-on: https://boringssl-review.googlesource.com/7782
Reviewed-by: Adam Langley <agl@google.com>
2016-04-27 19:25:25 +00:00
David Benjamin 862c0aa880 Revert md_len removal from SHA256_CTX and SHA512_CTX.
This reverts commits:
- 9158637142
- a90aa64302
- c0d8b83b44

It turns out code outside of BoringSSL also mismatches Init and Update/Final
functions. Since this is largely cosmetic, it's probably not worth the cost to
do this.

Change-Id: I14e7b299172939f69ced2114be45ccba1dbbb704
Reviewed-on: https://boringssl-review.googlesource.com/7793
Reviewed-by: Adam Langley <agl@google.com>
2016-04-27 19:01:23 +00:00
David Benjamin 88e27bcbe0 Don't mismatch Init and Update/Final hash functions.
Fixes the ASan bot.

Change-Id: I29b9b98680b634c5e486a734afa38f9d4e458518
Reviewed-on: https://boringssl-review.googlesource.com/7792
Reviewed-by: Adam Langley <agl@google.com>
2016-04-27 18:53:00 +00:00
David Benjamin 9158637142 Make SHA256_Final actually only return one.
As with SHA512_Final, use the different APIs rather than store md_len.

Change-Id: Ie1150de6fefa96f283d47aa03de0f18de38c93eb
Reviewed-on: https://boringssl-review.googlesource.com/7722
Reviewed-by: Adam Langley <agl@google.com>
2016-04-27 18:46:17 +00:00
David Benjamin a90aa64302 Pull HASH_MAKE_STRING out of md32_common.h.
This is in preparation for taking md_len out of SHA256_CTX by allowing us to do
something similar to SHA512_CTX. md32_common.h now emits a static "finish"
function which Final composes with the extraction step.

Change-Id: I314fb31e2482af642fd280500cc0e4716aef1ac6
Reviewed-on: https://boringssl-review.googlesource.com/7721
Reviewed-by: Adam Langley <agl@google.com>
2016-04-27 18:45:12 +00:00
David Benjamin e3118b8dc4 Fix Windows build.
Change-Id: Ie35b8d0e2da0f7d2588c4a436fc4b2b2596aaf18
Reviewed-on: https://boringssl-review.googlesource.com/7791
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-27 18:44:58 +00:00
David Benjamin c0d8b83b44 Make SHA512_Final actually only return one.
Rather than store md_len, factor out the common parts of SHA384_Final and
SHA512_Final and then extract the right state. Also add a missing
SHA384_Transform and be consistent about "1" vs "one" in comments.

This also removes the NULL output special-case which no other hash function
had.

Change-Id: If60008bae7d7d5b123046a46d8fd64139156a7c5
Reviewed-on: https://boringssl-review.googlesource.com/7720
Reviewed-by: Adam Langley <agl@google.com>
2016-04-27 18:42:37 +00:00
David Benjamin 3baee2a495 Banish SSL_add_dir_cert_subjects_to_stack and OPENSSL_DIR_CTX to decrepit.
There was only one function that required BoringSSL to know how to read
directories. Unfortunately, it does have some callers and it's not immediately
obvious whether the code is unreachable. Rather than worry about that, just
toss it all into decrepit.

In doing so, do away with the Windows and PNaCl codepaths. Only implement
OPENSSL_DIR_CTX on Linux.

Change-Id: Ie64d20254f2f632fadc3f248bbf5a8293ab2b451
Reviewed-on: https://boringssl-review.googlesource.com/7661
Reviewed-by: Adam Langley <agl@google.com>
2016-04-27 18:40:25 +00:00
Adam Langley 724dcbf5e2 Correct markdown misinterpretation.
The term “#define”, when the line breaking happens to put at the
beginning of a line, confuses markdown. This change escapes the '#'.

Change-Id: I8300324f9e8c7561f32aba6fa29c0132a188a58b
2016-04-27 11:09:31 -07:00
Adam Langley a081423809 Add document about incorporating BoringSSL into a project.
Change-Id: Ia825300bae236e3133dd9a19313b7f5450f0c8e2
Reviewed-on: https://boringssl-review.googlesource.com/7781
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-27 18:04:37 +00:00
David Benjamin a9959f2f50 Work around Android mingw issues.
The copy of mingw-w64 used by Android isn't new enough and is missing half of
the INIT_ONCE definitions. (But not the other half, strangely.) Work around
this for now.

Change-Id: I5c7e89db481f932e03477e50cfb3cbacaeb630e6
Reviewed-on: https://boringssl-review.googlesource.com/7790
Reviewed-by: Adam Langley <agl@google.com>
2016-04-27 14:36:23 +00:00
Adam Langley 7909aa7c23 Pass array by reference in newhope speed test.
This is another thing that MSVC can't cope with:

..\tool\speed.cc(537) : error C2536: 'SpeedNewHope::<⋯>::SpeedNewHope::<⋯>::clientmsg' : cannot specify explicit initializer for arrays

Change-Id: I6b4cb430895f7794e9cef1b1c12b57ba5d537c64
2016-04-26 16:31:38 -07:00
Adam Langley e75f0530a0 More fixes for MSVC.
Change-Id: I2cde4d99974a28126452bb66c6e176b92b7f0bc9
2016-04-26 16:25:31 -07:00
Adam Langley bc57d55c9f Corrupt the newhope secret key directly.
Rather than use an internal function in a test (which would need an
OPENSSL_EXPORT to work in a shared-library build), this change corrupts
the secret key directly.

Change-Id: Iee501910b23a0affaa0639dcc773d6ea2d0c5a82
Reviewed-on: https://boringssl-review.googlesource.com/7780
Reviewed-by: Matt Braithwaite <mab@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-04-26 23:20:47 +00:00
Matt Braithwaite 945cf9a131 newhope: MSVC can't size array using static size_t
Change-Id: I5060b1a3e800db21d2205f11951b4ad8a5986133
Reviewed-on: https://boringssl-review.googlesource.com/7770
Reviewed-by: Adam Langley <agl@google.com>
2016-04-26 23:07:16 +00:00
Matt Braithwaite 045a0ffe35 Import `newhope' (post-quantum key exchange).
This derives from the reference implementation:

Source: https://github.com/tpoeppelmann/newhope/tree/master/ref at bc06c1ac
Paper: https://eprint.iacr.org/2015/1092

However, it does not interoperate, due to the replacement of SHAKE-128
with AES-CTR (for polynomial generation) and the replacement of SHA-3
with SHA-256 (for key whitening).

Change-Id: I6a55507aea85331245e2fbd41bae5cc049fdca3c
Reviewed-on: https://boringssl-review.googlesource.com/7690
Reviewed-by: Adam Langley <agl@google.com>
2016-04-26 22:53:59 +00:00
David Benjamin c25d2e6379 Resolve -Wextern-c-compat warnings with OPENSSL_NO_THREADS.
C and C++ disagree on the sizes of empty structs, which can be rather bad for
structs embedded in public headers. Stick a char in them to avoid issues. (It
doesn't really matter for CRYPTO_STATIC_MUTEX, but it's easier to add a char in
there too.)

Thanks to Andrew Chi for reporting this issue.

Change-Id: Ic54fff710b688decaa94848e9c7e1e73f0c58fd3
Reviewed-on: https://boringssl-review.googlesource.com/7760
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-26 22:19:51 +00:00
Steven Valdez ede2e2c5ce Fix buffer overrun in ASN1_parse() and signed/unsigned warning.
(Imported from upstream's 2442382e11c022aaab4fdc6975bd15d5a75c4db2 and
0ca67644ddedfd656d43a6639d89a6236ff64652)

Change-Id: I601ef07e39f936e8f3e30412fd90cd339d712dc4
Reviewed-on: https://boringssl-review.googlesource.com/7742
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-26 18:49:09 +00:00
Steven Valdez b32a9151da Ensure we check i2d_X509 return val
The i2d_X509() function can return a negative value on error. Therefore
we should make sure we check it.

Issue reported by Yuan Jochen Kang.

(Imported from upstream's 8f43c80bfac15544820739bf035df946eeb603e8)

Change-Id: If247d5bf1d792eb7c6dc179b606ed21ea0ccdbb8
Reviewed-on: https://boringssl-review.googlesource.com/7743
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-26 17:12:01 +00:00
Steven Valdez 14b07a02a6 Harden ASN.1 BIO handling of large amounts of data.
If the ASN.1 BIO is presented with a large length field read it in
chunks of increasing size checking for EOF on each read. This prevents
small files allocating excessive amounts of data.

CVE-2016-2109

Thanks to Brian Carpenter for reporting this issue.

(Imported from upstream's f32774087f7b3db1f789688368d16d917757421e)

Change-Id: Id1b0d4436c4879d0ba7d3b7482b937cafffa28f7
Reviewed-on: https://boringssl-review.googlesource.com/7741
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-26 17:06:16 +00:00
David Benjamin f040d3c7e1 Fix build.
Forgot to mark something static.

Change-Id: I497075d0ad27e2062f84528fb568b333e72a7d3b
Reviewed-on: https://boringssl-review.googlesource.com/7753
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-26 15:53:09 +00:00
David Benjamin dc9194f78b Fix a bug in obj_dat.pl and add basic crypto/obj tests.
It's not possible to encode an OID with only one component, so some of
the NIDs do not have encodings. The logic to actually encode OIDs checks
for this (before calling der_it), but not the logic to compute the
sorted OID list.

Without this, OBJ_obj2nid, when given an empty OID, returns something
arbitrary based on the binary search implementation instead of
NID_undef.

Change-Id: Ib68bae349f66eff3d193616eb26491b6668d4b0a
Reviewed-on: https://boringssl-review.googlesource.com/7752
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-26 15:19:26 +00:00
David Benjamin f13444a5ad Use different bit tricks to extend the LSB.
C gets grumpy when you shift into a sign bit. Replace it with a different bit
trick.

BUG=chromium:603502

Change-Id: Ia4cc2e2d68675528b7c0155882ff4d6230df482b
Reviewed-on: https://boringssl-review.googlesource.com/7740
Reviewed-by: Adam Langley <agl@google.com>
2016-04-25 23:05:20 +00:00
David Benjamin 1fc7564ba7 Add standalone PKCS#8 and SPKI fuzzers.
We already had coverage for our new EVP_PKEY parsers, but it's good to have
some that cover them directly. The initial corpus was generated manually with
der-ascii and should cover most of the insanity around EC key serialization.

BUG=15

Change-Id: I7aaf56876680bfd5a89f5e365c5052eee03ba862
Reviewed-on: https://boringssl-review.googlesource.com/7728
Reviewed-by: Adam Langley <agl@google.com>
2016-04-25 21:57:28 +00:00
David Benjamin af18cdd733 Add a copyright header to run_android_tests.go.
Change-Id: Ifd60964e4074fa7900e9ebfbb669864bae0821dd
Reviewed-on: https://boringssl-review.googlesource.com/7729
Reviewed-by: Adam Langley <agl@google.com>
2016-04-25 21:55:36 +00:00
David Benjamin 6e96d2be3d Remove stale wpa_supplicant hacks.
aosp-master has been updated past the point that this is necessary. Sadly, all
the other hacks still are. I'll try to get things rolling so we can ditch the
others in time.

Change-Id: If7b3aad271141fb26108a53972d2d3273f956e8d
Reviewed-on: https://boringssl-review.googlesource.com/7751
Reviewed-by: Adam Langley <agl@google.com>
2016-04-25 21:19:12 +00:00
David Benjamin 1be6a7e442 Add another temporary hack for wpa_supplicant.
Due to Android's complex branching scheme, we have to keep building against a
snapshotted version of wpa_supplicant. wpa_supplicant, in preparation for
OpenSSL 1.1.0, added compatibility versions of some accessors that we, in
working towards opaquification, have imported. This causes a conflict (C does
not like having static and non-static functions share a name).

Add a hack in the headers to suppress the conflicting accessors when
BORINGSSL_SUPPRESS_ACCESSORS is defined. Android releases which include an
updated BoringSSL will also locally carry this #define in wpa_supplicant build
files. Once we can be sure releases of BoringSSL will only see a new enough
wpa_supplicant (one which includes a to-be-submitted patch), we can ditch this.

Change-Id: I3e27fde86bac1e59077498ee5cbd916cd880821e
Reviewed-on: https://boringssl-review.googlesource.com/7750
Reviewed-by: Adam Langley <agl@google.com>
2016-04-25 21:18:37 +00:00
Adam Langley b70cd92c82 Add licenses to fuzz tests.
These source files previously didn't have the ISC license on them.

Change-Id: Ic0a2047d23b28d9d7f0a85b2fedb67574bdcab25
Reviewed-on: https://boringssl-review.googlesource.com/7735
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-25 20:15:27 +00:00
Adam Langley 3d907ed964 Remove RC4_options from rc4-586.pl.
The x86-64 version of this assembly doesn't include this function. It's
in decrepit/rc4 as a compatibility backfill but that means that 32-bit
builds end up with two definitions of this symbol.

Change-Id: Ib6da6b91aded8efc679ebbae6d60c96a78f3dc4e
Reviewed-on: https://boringssl-review.googlesource.com/7734
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-22 21:14:11 +00:00
David Benjamin 38d01c6b95 Improve generate_build_files.py gn support.
Split gn and gyp generators apart. Since we're pre-generating files, there's no
need to make BoringSSL's build depend on the gypi_to_gn.py script. Also emit
the tests and a list of fuzzers so we don't need to manually update BUILD.gn
each time.

The new gn generator is based on the bazel one since they're fairly similar.

BUG=chromium:429246

Change-Id: I5a819a964d6ac6e56e9251bb3fd3de1db08214a4
Reviewed-on: https://boringssl-review.googlesource.com/7726
Reviewed-by: Adam Langley <agl@google.com>
2016-04-22 18:56:55 +00:00
David Benjamin 818aff01fb Add SSL_SESSION_get_master_key.
Opaquifying SSL_SESSION is less important than the other structs, but this will
cause less turbulence in wpa_supplicant if we add this API too. Semantics and
name taken from OpenSSL 1.1.0 to match.

BUG=6

Change-Id: Ic39f58d74640fa19a60aafb434dd2c4cb43cdea9
Reviewed-on: https://boringssl-review.googlesource.com/7725
Reviewed-by: Adam Langley <agl@google.com>
2016-04-21 21:14:36 +00:00
David Benjamin 7fadfc6135 Move TLS-specific "AEAD" functions to the bottom of aead.h.
Probably better to keep it out of the way for someone just trying to figure out
how to use the library. Notably, we don't really want people to think they need
to use the directioned init function.

Change-Id: Icacc2061071581abf46e38eb1d7a52e7b1f8361b
Reviewed-on: https://boringssl-review.googlesource.com/7724
Reviewed-by: Adam Langley <agl@google.com>
2016-04-21 20:34:41 +00:00
David Benjamin 325664eec4 Add hkdf.h to doc.config.
It has all of one function in there.

Change-Id: I86f0fbb76d267389c62b63ac01df685acb70535e
Reviewed-on: https://boringssl-review.googlesource.com/7723
Reviewed-by: Adam Langley <agl@google.com>
2016-04-21 20:25:15 +00:00
Brian Smith f01fb5dc0e Avoid minor waste in |ec_GFp_nistp256_point_get_affine_coordinates|.
Avoid calculating the affine Y coordinate when the caller didn't ask
for it, as occurs, for example, in ECDH.

For symmetry and clarity, avoid calculating the affine X coordinate in
the hypothetical case where the caller only asked for the Y coordinate.

Change-Id: I69f5993fa0dfac8b010c38e695b136cefc277fed
Reviewed-on: https://boringssl-review.googlesource.com/7590
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-20 23:00:27 +00:00
Brian Smith 3f3358ac15 Save one call to |ecp_nistz256_from_mont| in |ecp_nistz256_get_affine|.
Change-Id: I38faa5c4e9101c100614ebadf421bde0a05af360
Reviewed-on: https://boringssl-review.googlesource.com/7589
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-20 22:58:36 +00:00
Brian Smith a7aa2bb8f8 Avoid a multiplication in |ecp_nistz256_get_affine| when |x| is NULL.
This is purely hypothetical, as in real life nobody cares about the
|y| component without also caring about the |x| component, but it
clarifies the code and makes a future change clearer.

Change-Id: Icaa4de83c87b82a8e68cd2942779a06e5db300c3
Reviewed-on: https://boringssl-review.googlesource.com/7588
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-20 22:53:46 +00:00
Brian Smith d860b7b1cd Set output coordinates' |neg| field in |ecp_nistz256_get_affine|.
The result would not be correct if, on input, |x->neg != 0| or
|y->neg != 0|.

Change-Id: I645566a78c2e18e42492fbfca1df17baa05240f7
Reviewed-on: https://boringssl-review.googlesource.com/7587
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-20 22:52:45 +00:00
Brian Smith 97770d17d8 Use only Montgomery math in |ec_GFp_mont_point_get_affine_coordinates|.
Use only Montgomery math in |ec_GFp_mont_point_get_affine_coordinates|.
In particular, avoid |BN_mod_sqr| and |BN_mod_mul|.

Change-Id: I05c8f831d2865d1b105cda3871e9ae67083f8399
Reviewed-on: https://boringssl-review.googlesource.com/7586
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-20 22:51:34 +00:00
David Benjamin f3835839b1 Use nanosleep instead of usleep.
usleep is guarded by feature macro insanity. Use nanosleep which looks to be
less unfriendly.

Change-Id: I75cb2284f26cdedabb19871610761ec7440b6ad3
Reviewed-on: https://boringssl-review.googlesource.com/7710
Reviewed-by: Emily Stark (Dunn) <estark@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-19 21:54:26 +00:00
David Benjamin 9dadc3b6e1 Replace CRYPTO_once_t on Windows with INIT_ONCE.
Now that we no longer support Windows XP, this function is available. In doing
so, remove the odd run_once_arg_t union and pass in a pointer to a function
pointer which is cleaner and still avoids C's silly rule where function
pointers can't be placed in a void*.

BUG=37

Change-Id: I44888bb3779dacdb660706debd33888ca389ebd5
Reviewed-on: https://boringssl-review.googlesource.com/7613
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-19 21:34:20 +00:00
David Benjamin 3ed24f0502 Test CRYPTO_once_t collisions.
The existing tests never actually tested this case.

Change-Id: Idb9cf0cbbe32fdf5cd353656a95fbedbaac09376
Reviewed-on: https://boringssl-review.googlesource.com/7612
Reviewed-by: Emily Stark (Dunn) <estark@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-19 21:33:59 +00:00
David Benjamin 582d2847ed Reimplement PKCS#12 key derivation.
This is avoids pulling in BIGNUM for doing a straight-forward addition on a
block-sized value, and avoids a ton of mallocs. It's also -Wconversion-clean,
unlike the old one.

In doing so, this replaces the HMAC_MAX_MD_CBLOCK with EVP_MAX_MD_BLOCK_SIZE.
By having the maximum block size available, most of the temporary values in the
key derivation don't need to be malloc'd.

BUG=22

Change-Id: I940a62bba4ea32bf82b1190098f3bf185d4cc7fe
Reviewed-on: https://boringssl-review.googlesource.com/7688
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-19 18:16:38 +00:00
David Benjamin 0e21f41fe8 Switch all 'num' parameters in crypto/modes to unsigned.
Also switch the EVP_CIPHER copy to cut down on how frequently we need to cast
back and forth.

BUG=22

Change-Id: I9af1e586ca27793a4ee6193bbb348cf2b28a126e
Reviewed-on: https://boringssl-review.googlesource.com/7689
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-19 17:56:25 +00:00
David Benjamin 1a0a8b6760 Make EVP_MD_CTX size functions return size_t.
The EVP_MD versions do, so the types should bubble up.

BUG=22

Change-Id: Ibccbc9ff35bbfd3d164fc28bcdd53ed97c0ab338
Reviewed-on: https://boringssl-review.googlesource.com/7687
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-19 15:12:41 +00:00
Brian Smith 86361a3910 Require the public exponent to be available in RSA blinding.
Require the public exponent to be available unless
|RSA_FLAG_NO_BLINDING| is set on the key. Also, document this.

If the public exponent |e| is not available, then we could compute it
from |p|, |q|, and |d|. However, there's no reasonable situation in
which we'd have |p| or |q| but not |e|; either we have all the CRT
parameters, or we have (e, d, n), or we have only (d, n). The
calculation to compute |e| exposes the private key to risk of side
channel attacks.

Also, it was particularly wasteful to compute |e| for each
|BN_BLINDING| created, instead of just once before the first
|BN_BLINDING| was created.

|BN_BLINDING| now no longer needs to contain a duplicate copy of |e|,
so it is now more space-efficient.

Note that the condition |b->e != NULL| in |bn_blinding_update| was
always true since commit cbf56a5683.

Change-Id: Ic2fd6980e0d359dcd53772a7c31bdd0267e316b4
Reviewed-on: https://boringssl-review.googlesource.com/7594
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-18 23:34:46 +00:00
Brian Smith d035730ac7 Make return value of |BN_MONT_CTX_set_locked| int.
This reduces the chance of double-frees.

BUG=10

Change-Id: I11a240e2ea5572effeddc05acb94db08c54a2e0b
Reviewed-on: https://boringssl-review.googlesource.com/7583
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-18 23:19:08 +00:00
Brian Smith 51b0d5b1e8 Do not use the CRT when |rsa->e == NULL|.
When |rsa->e == NULL| we cannot verify the result, so using the CRT
would leave the key too vulnerable to fault attacks.

Change-Id: I154622cf6205ba4d5fb219143db6072a787c2d1f
Reviewed-on: https://boringssl-review.googlesource.com/7581
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-18 22:50:24 +00:00
Brian Smith 69f0532c85 Use |memcmp| instead of |CRYPTO_memcmp| in |RSA_verify|.
|CRYPTO_memcmp| isn't necessary because there is no secret data being
acted on here.

Change-Id: Ib678d5d4fc16958aca409a93df139bdff8cb73fb
Reviewed-on: https://boringssl-review.googlesource.com/7465
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-18 20:42:22 +00:00
Brian Smith 2a92031bb4 Clarify |RSA_verify_raw| error handling & cleanup.
Use the common pattern of returning early instead of |goto err;| when
there's no cleanup to do yet. Also, move the error checking of
|BN_CTX_get| failure closer to the the calls to |BN_CTX_get|. Avoid
calling |OPENSSL_cleanse| on public data. Clarify when/why |buf| is not
freed.

Change-Id: I9df833db7eb7041c5af9349c461297372b988f98
Reviewed-on: https://boringssl-review.googlesource.com/7464
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-18 20:42:15 +00:00
Brian Smith 9902262af6 Remove redundant check of |sig_len| in |RSA_verify|.
The same check is already done in |RSA_verify_raw|, so |RSA_verify|
doesn't need to do it.

Also, move the |RSA_verify_raw| check earlier.

Change-Id: I15f7db0aad386c0f764bba53e77dfc46574f7635
Reviewed-on: https://boringssl-review.googlesource.com/7463
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-18 20:40:41 +00:00
Brian Smith c0b196d4eb Drop support for engines-provided signature verification.
We do not need to support engine-provided verification methods.

Change-Id: Iaad8369d403082b728c831167cc386fdcabfb067
Reviewed-on: https://boringssl-review.googlesource.com/7311
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-18 20:40:17 +00:00
David Benjamin 9b611e28e4 Simplify server_name extension parsing.
Although the server_name extension was intended to be extensible to new name
types, OpenSSL 1.0.x had a bug which meant different name types will cause an
error. Further, RFC 4366 originally defined syntax inextensibly. RFC 6066
corrected this mistake, but adding new name types is no longer feasible.

Act as if the extensibility does not exist to simplify parsing. This also
aligns with OpenSSL 1.1.x's behavior. See upstream's
062178678f5374b09f00d70796f6e692e8775aca and
https://www.ietf.org/mail-archive/web/tls/current/msg19425.html

Change-Id: I5af26516e8f777ddc1dab5581ff552daf2ea59b5
Reviewed-on: https://boringssl-review.googlesource.com/7294
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-18 20:33:35 +00:00
David Benjamin 4c5ddb8047 Set rwstate consistently.
We reset it to SSL_NOTHING at the start of ever SSL_get_error-using operation.
Then we only set it to a non-NOTHING value in the rest of the stack on error
paths.

Currently, ssl->rwstate is set all over the place. Sometimes the pattern is:

  ssl->rwstate = SSL_WRITING;
  if (BIO_write(...) <= 0) {
    goto err;
  }
  ssl->rwstate = SSL_NOTHING;

Sometimes we only set it to the non-NOTHING value on error.

  if (BIO_write(...) <= 0) {
    ssl->rwstate = SSL_WRITING;
  }
  ssl->rwstate = SSL_NOTHING;

Sometimes we just set it to SSL_NOTHING far from any callback in random places.

The third case is arbitrary and clearly should be removed.

But, in the second case, we sometimes forget to undo it afterwards. This is
largely harmless since an error in the error queue overrides rwstate, but we
don't always put something in the error queue (falling back to
SSL_ERROR_SYSCALL for "I'm not sure why it failed. Perhaps it was one of your
callbacks? Check your errno equivalent."), but in that case a stray rwstate
value will cause it to be wrong.

We could fix the cases where we fail to set SSL_NOTHING on success cases, but
this doesn't account for there being multiple SSL_get_error operations. The
consumer may have an SSL_read and an SSL_write running concurrently. Instead,
it seems the best option is to lift the SSL_NOTHING reset to the operations and
set SSL_WRITING and friends as in the second case.

(Someday hopefully we can fix this to just be an enum that is internally
returned. It can convert to something stateful at the API layer.)

Change-Id: I54665ec066a64eb0e48a06e2fcd0d2681a42df7f
Reviewed-on: https://boringssl-review.googlesource.com/7453
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-18 20:30:32 +00:00
David Benjamin c6972eb1f0 Remove the no_renegotiation special case.
The concern is if the peer denies our renegotiation attempt, but we will never
initiate renegotiation. We only support server-initiated renegotiation when we
are acting as the client.

(Strictly speaking, only the client ever initiates renegotiation. The server
sends a HelloRequest to ask the client to initiate it. But we forbid
application data interleave as soon as we see the HelloRequest, so we treat it
as part of the handshake.)

Change-Id: I1a625130de32a7227e4471f2f889255aba962ce4
Reviewed-on: https://boringssl-review.googlesource.com/7452
Reviewed-by: Emily Stark (Dunn) <estark@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-18 20:29:30 +00:00
David Benjamin 0d3a8c6ac0 Don't allow alert records with multiple alerts.
This is just kind of a silly thing to do. NSS doesn't allow them either. Fatal
alerts would kill the connection regardless and warning alerts are useless. We
previously stopped accepting fragmented alerts but still allowed them doubled
up.

This is in preparation for pulling the shared alert processing code between TLS
and DTLS out of read_bytes into some common place.

Change-Id: Idbef04e39ad135f9601f5686d41f54531981e0cf
Reviewed-on: https://boringssl-review.googlesource.com/7451
Reviewed-by: Emily Stark (Dunn) <estark@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-18 20:29:02 +00:00
David Benjamin 56703d91bf Make err_data_generator.go silent by default.
I don't think I ever look at that output. This way our builds are nice and
silent.

Change-Id: Idb215e3702f530a8b8661622c726093530885c91
Reviewed-on: https://boringssl-review.googlesource.com/7700
Reviewed-by: Adam Langley <agl@google.com>
2016-04-18 19:42:15 +00:00
David Benjamin 26993ad55e Only use recv/send for socket BIOs on Windows.
In OpenSSL, socket BIOs only used recv/send on Windows and read/write on POSIX.
Align our socket BIOs with that behavior. This should be a no-op, but avoids
frustrating consumers overly sensitive to the syscalls used now that SSL_set_fd
has switched to socket BIOs to align with OpenSSL. b/28138582.

Change-Id: Id4870ef8e668e587d6ef51c5b5f21e03af66a288
Reviewed-on: https://boringssl-review.googlesource.com/7686
Reviewed-by: Adam Langley <agl@google.com>
2016-04-15 20:31:05 +00:00
David Benjamin 919610b4c4 Fix memory leak on invalid ecPublicKey parameters.
One of the codepaths didn't free the group. Found by libFuzzer.

BUG=chromium:603893

Change-Id: Icb81f2f89a8c1a52e29069321498986b193a0e56
Reviewed-on: https://boringssl-review.googlesource.com/7685
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: Adam Langley <agl@google.com>
2016-04-15 19:43:26 +00:00
Daniel Bathgate 4365c3f522 Send an error rather than assert when decrypt_len != rsa_size.
With SSL_PRIVATE_KEY_METHOD, decryption can happen outside of BoringSSL. Rather than crash the process, it would be nicer if BoringSSL handled the error gracefully.

Change-Id: I3f24d066f7a329d41420b208a7e13c82ec966710
Reviewed-on: https://boringssl-review.googlesource.com/7683
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-14 22:19:40 +00:00
David Benjamin 0fe4d8bef5 chacha/asm/chacha-armv8.pl: fix intermittent build failures.
(Imported from b9077d85b0042d3d5d877d5cf7f06a8a8c035673.)

Change-Id: I6df3b3d0913b001712a78671c69b9468e059047f
Reviewed-on: https://boringssl-review.googlesource.com/7682
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-14 20:50:36 +00:00
Steven Valdez 9980ce1dcd Add BORINGSSL_PREFIX for prefixing symbols
This currently doesn't prefix assembly symbols since they don't pull in
openssl/base.h

BUG=5

Change-Id: Ie0fdc79ae73099f84ecbf3f17604a1e615569b3b
Reviewed-on: https://boringssl-review.googlesource.com/7681
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-14 20:49:31 +00:00
David Benjamin a82e8dd9d2 Tweak X25519 documentation.
Both the header-level and section-level documentation define curve25519 which
is a little odd.

Change-Id: I81aa2b74e8028d3cfd5635e1d3cfda402ba1ae38
Reviewed-on: https://boringssl-review.googlesource.com/7680
Reviewed-by: Adam Langley <agl@google.com>
2016-04-14 14:20:56 +00:00
Adam Langley aaccbfec04 Export RSA_padding_add_PKCS1_OAEP[_mgf1]
This is needed by trousers. As with the PSS function, the version that
assumes SHA-1 is put into decrepit.

Change-Id: I153e8ea0150e48061b978384b600a7b990d21d03
Reviewed-on: https://boringssl-review.googlesource.com/7670
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-13 21:15:20 +00:00
Max Moroz 188487faad Remove .options files for libFuzzers and update FUZZING.md documentation.
Due to https://codereview.chromium.org/1867833002/ replacing .options files.

Change-Id: I17f0d5b8b1784fdcf163791e72f6b58b29657e95
Reviewed-on: https://boringssl-review.googlesource.com/7640
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-12 14:56:57 +00:00
David Benjamin e4c678adda Revert "Banish SSL_add_dir_cert_subjects_to_stack and OPENSSL_DIR_CTX to decrepit."
This reverts commit 112c4dd1ff. Accidentally used
the wrong push line.
2016-04-11 18:04:18 -04:00
David Benjamin 112c4dd1ff Banish SSL_add_dir_cert_subjects_to_stack and OPENSSL_DIR_CTX to decrepit.
There was only one function that required BoringSSL to know how to read
directories. Unfortunately, it does have some callers and it's not immediately
obvious whether the code is unreachable. Rather than worry about that, just
toss it all into decrepit.

In doing so, do away with the Windows and PNaCl codepaths. Only implement
OPENSSL_DIR_CTX on Linux.

Change-Id: I3eb55b098e3aa042b422bb7da115c0812685553e
2016-04-11 18:01:54 -04:00
David Benjamin 2a187a4316 No-op change to test bugdroid.
Making sure the BUG= line works correctly.

BUG=41

Change-Id: Icedf5f1ec8211696c74d9e9f9d322483c43444fc
2016-04-11 17:26:50 -04:00
David Benjamin 14420e91e0 Remove EVP_aead_chacha20_poly1305_rfc7539 alias.
This slipped through, but all the callers are now using
EVP_aead_chacha20_poly1305, so we can remove this version.

Change-Id: I76eb3a4481aae4d18487ca96ebe3776e60d6abe8
Reviewed-on: https://boringssl-review.googlesource.com/7650
Reviewed-by: Steven Valdez <svaldez@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-11 19:32:55 +00:00
Piotr Sikora a13ad73cee Use UINT64_C instead of unsigned long long integer constant.
Change-Id: Id181957956ccaacc6c29b641a1f1144886d442c0
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Reviewed-on: https://boringssl-review.googlesource.com/7630
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-11 16:08:14 +00:00
Gabriel Redner dcb3383463 Modify 'bssl client' to print the cert subject and issuer
This is the one piece of functionality I miss from the openssl tool -
the ability to see some basic information about the server cert.

Sample output:
==========
$ bssl client -connect www.google.com
Connecting to [2607:f8b0:4006:80d::1010]:443
Connected.
  Version: TLSv1.2
  Resumed session: no
  Cipher: ECDHE-RSA-AES128-GCM-SHA256
  ECDHE curve: P-256
  Secure renegotiation: yes
  Next protocol negotiated:
  ALPN protocol:
  Cert subject: /C=US/ST=California/L=Mountain View/O=Google Inc/CN=www.google.com
  Cert issuer: /C=US/O=Google Inc/CN=Google Internet Authority G2
==========

Change-Id: I758682784752a616628138e420f52586d5a1bb31
Reviewed-on: https://boringssl-review.googlesource.com/7620
Reviewed-by: David Benjamin <davidben@google.com>
2016-04-07 03:22:19 +00:00
412 changed files with 13863 additions and 8720 deletions
+3
View File
@@ -2,3 +2,6 @@ BasedOnStyle: Google
MaxEmptyLinesToKeep: 3
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
DerivePointerAlignment: false
PointerAlignment: Right
+13 -9
View File
@@ -24,13 +24,17 @@
by CMake, it may be configured explicitly by setting
`CMAKE_ASM_NASM_COMPILER`.
* A C compiler is required. On Windows, MSVC 12 (Visual Studio 2013) or later
* A C compiler is required. On Windows, MSVC 14 (Visual Studio 2015) or later
with Platform SDK 8.1 or later are supported. Recent versions of GCC (4.8+)
and Clang should work on non-Windows platforms, and maybe on Windows too.
To build the tests, you also need a C++ compiler with C++11 support.
* [Go](https://golang.org/dl/) is required. If not found by CMake, the go
executable may be configured explicitly by setting `GO_EXECUTABLE`.
* To build the x86 and x86\_64 assembly, your assembler must support AVX2
instructions. If using GNU binutils, you must have 2.22 or later.
## Building
Using Ninja (note the 'N' is capitalized in the cmake invocation):
@@ -79,18 +83,18 @@ It's possible to build BoringSSL with the Android NDK using CMake. This has
been tested with version 10d of the NDK.
Unpack the Android NDK somewhere and export `ANDROID_NDK` to point to the
directory. Clone https://github.com/taka-no-me/android-cmake into `util/`. Then
make a build directory as above and run CMake *twice* like this:
directory. Then make a build directory as above and run CMake like this:
cmake -DANDROID_NATIVE_API_LEVEL=android-9 \
-DANDROID_ABI=armeabi-v7a \
-DCMAKE_TOOLCHAIN_FILE=../util/android-cmake/android.toolchain.cmake \
cmake -DANDROID_ABI=armeabi-v7a \
-DCMAKE_TOOLCHAIN_FILE=../third_party/android-cmake/android.toolchain.cmake \
-DANDROID_NATIVE_API_LEVEL=16 \
-GNinja ..
Once you've run that twice, Ninja should produce Android-compatible binaries.
You can replace `armeabi-v7a` in the above with `arm64-v8a` to build aarch64
binaries.
Once you've run that, Ninja should produce Android-compatible binaries. You
can replace `armeabi-v7a` in the above with `arm64-v8a` and use API level 21 or
higher to build aarch64 binaries.
For other options, see [android-cmake's documentation](./third_party/android-cmake/README.md).
## Known Limitations on Windows
+30 -24
View File
@@ -15,8 +15,12 @@ enable_language(CXX)
if(ANDROID)
# Android-NDK CMake files reconfigure the path and so Go and Perl won't be
# found. However, ninja will still find them in $PATH if we just name them.
set(PERL_EXECUTABLE "perl")
set(GO_EXECUTABLE "go")
if(NOT PERL_EXECUTABLE)
set(PERL_EXECUTABLE "perl")
endif()
if(NOT GO_EXECUTABLE)
set(GO_EXECUTABLE "go")
endif()
else()
find_package(Perl REQUIRED)
find_program(GO_EXECUTABLE go)
@@ -29,7 +33,7 @@ endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(C_CXX_FLAGS "-Wall -Werror -Wformat=2 -Wsign-compare -Wmissing-field-initializers -ggdb -fvisibility=hidden")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${C_CXX_FLAGS} -Wmissing-prototypes")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x ${C_CXX_FLAGS} -Wmissing-declarations")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ${C_CXX_FLAGS} -Wmissing-declarations")
elseif(MSVC)
set(MSVC_DISABLED_WARNINGS_LIST
"C4100" # 'exarg' : unreferenced formal parameter
@@ -51,6 +55,7 @@ elseif(MSVC)
"C4365" # '=' : conversion from 'size_t' to 'int',
# signed/unsigned mismatch
"C4389" # '!=' : signed/unsigned mismatch
"C4464" # relative include path contains '..'
"C4510" # 'argument' : default constructor could not be generated
"C4512" # 'argument' : assignment operator could not be generated
"C4514" # 'function': unreferenced inline function has been removed
@@ -58,6 +63,7 @@ elseif(MSVC)
# side-effect" caused by FD_* macros.
"C4610" # struct 'argument' can never be instantiated - user defined
# constructor required.
"C4623" # default constructor was implicitly defined as deleted
"C4625" # copy constructor could not be generated because a base class
# copy constructor is inaccessible or deleted
"C4626" # assignment operator could not be generated because a base class
@@ -68,31 +74,22 @@ elseif(MSVC)
"C4800" # 'int' : forcing value to bool 'true' or 'false'
# (performance warning)
"C4820" # 'bytes' bytes padding added after construct 'member_name'
"C4996" # 'read': The POSIX name for this item is deprecated. Instead,
# use the ISO C++ conformant name: _read.
)
if(NOT(CMAKE_C_COMPILER_VERSION VERSION_LESS "19.0.23506"))
# MSVC 2015 Update 1.
set(MSVC_DISABLED_WARNINGS_LIST
${MSVC_DISABLED_WARNINGS_LIST}
"C4464" # relative include path contains '..'
"C4623" # default constructor was implicitly defined as deleted
"C5027" # move assignment operator was implicitly defined as deleted
)
set(MSVC_LEVEL4_WARNINGS_LIST
# See https://connect.microsoft.com/VisualStudio/feedback/details/1217660/warning-c4265-when-using-functional-header
"C4265" # class has virtual functions, but destructor is not virtual
)
string(REPLACE "C" " -w4" MSVC_LEVEL4_WARNINGS_STR
${MSVC_LEVEL4_WARNINGS_LIST})
endif()
"C5027" # move assignment operator was implicitly defined as deleted
)
set(MSVC_LEVEL4_WARNINGS_LIST
# See https://connect.microsoft.com/VisualStudio/feedback/details/1217660/warning-c4265-when-using-functional-header
"C4265" # class has virtual functions, but destructor is not virtual
)
string(REPLACE "C" " -wd" MSVC_DISABLED_WARNINGS_STR
${MSVC_DISABLED_WARNINGS_LIST})
string(REPLACE "C" " -w4" MSVC_LEVEL4_WARNINGS_STR
${MSVC_LEVEL4_WARNINGS_LIST})
set(CMAKE_C_FLAGS "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR} ${MSVC_LEVEL4_WARNINGS_STR}")
set(CMAKE_CXX_FLAGS "-Wall -WX ${MSVC_DISABLED_WARNINGS_STR} ${MSVC_LEVEL4_WARNINGS_STR}")
add_definitions(-D_HAS_EXCEPTIONS=0)
add_definitions(-DWIN32_LEAN_AND_MEAN)
add_definitions(-DNOMINMAX)
add_definitions(-D_CRT_SECURE_NO_WARNINGS) # Allow use of fopen
endif()
if((CMAKE_COMPILER_IS_GNUCXX AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.7.99") OR
@@ -101,9 +98,18 @@ if((CMAKE_COMPILER_IS_GNUCXX AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.7.9
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wshadow")
endif()
if((CMAKE_COMPILER_IS_GNUCXX AND CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.8.99") OR
CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -D_XOPEN_SOURCE=700")
if(CMAKE_COMPILER_IS_GNUCXX)
if ((CMAKE_C_COMPILER_VERSION VERSION_GREATER "4.8.99") OR
CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
endif()
endif()
# pthread_rwlock_t requires a feature flag.
if(NOT WIN32)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_XOPEN_SOURCE=700")
endif()
if(FUZZ)
+13 -1
View File
@@ -28,7 +28,19 @@ From the `build/` directory, you can then run the fuzzers. For example:
The arguments to `jobs` and `workers` should be the number of cores that you wish to dedicate to fuzzing. By default, libFuzzer uses the largest test in the corpus (or 64 if empty) as the maximum test case length. The `max_len` argument overrides this.
The recommended values of `max_len` for each test may be found in `.options` files alongside the test source. These were determined by rounding up the length of the largest case in the corpus. When writing a new fuzzer, configure `max_len` in a similar file.
The recommended values of `max_len` for each test are:
| Test | `max_len` value |
|------------|-----------------|
| `cert` | 3072 |
| `client` | 20000 |
| `pkcs8` | 2048 |
| `privkey` | 2048 |
| `server` | 4096 |
| `spki` | 1024 |
| `read_pem` | 512 |
These were determined by rounding up the length of the largest case in the corpus.
There are directories in `fuzz/` for each of the fuzzing tests which contain seed files for fuzzing. Some of the seed files were generated manually but many of them are “interesting” results generated by the fuzzing itself. (Where “interesting” means that it triggered a previously unknown path in the code.)
+90
View File
@@ -0,0 +1,90 @@
# Incorporating BoringSSL into a project
**Note**: if your target project is not a Google project then first read the
[main README](/README.md) about the purpose of BoringSSL.
## Directory layout
Typically projects create a `third_party/boringssl` directory to put
BoringSSL-specific files into. The source code of BoringSSL itself goes into
`third_party/boringssl/src`, either by copying or as a
[submodule](https://git-scm.com/docs/git-submodule).
It's generally a mistake to put BoringSSL's source code into
`third_party/boringssl` directly because pre-built files and custom build files
need to go somewhere and merging these with the BoringSSL source code makes
updating things more complex.
## Build support
BoringSSL is designed to work with many different build systems. Currently,
different projects use [GYP](https://gyp.gsrc.io/),
[GN](https://chromium.googlesource.com/chromium/src/+/master/tools/gn/docs/quick_start.md),
[Bazel](http://bazel.io/) and [Make](https://www.gnu.org/software/make/) to
build BoringSSL, without too much pain.
The development build system is CMake and the CMake build knows how to
automatically generate the intermediate files that BoringSSL needs. However,
outside of the CMake environment, these intermediates are generated once and
checked into the incorporating project's source repository. This avoids
incorporating projects needing to support Perl and Go in their build systems.
The script [`util/generate_build_files.py`](/util/generate_build_files.py)
expects to be run from the `third_party/boringssl` directory and to find the
BoringSSL source code in `src/`. You should pass it a single argument: the name
of the build system that you're using. If you don't use any of the supported
build systems then you should augment `generate_build_files.py` with support
for it.
The script will pregenerate the intermediate files (see
[BUILDING.md](/BUILDING.md) for details about which tools will need to be
installed) and output helper files for that build system. It doesn't generate a
complete build script, just file and test lists, which change often. For
example, see the
[file](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/boringssl/BUILD.generated.gni)
and
[test](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/boringssl/BUILD.generated_tests.gni)
lists generated for GN in Chromium.
Generally one checks in these generated files alongside the hand-written build
files. Periodically an engineer updates the BoringSSL revision, regenerates
these files and checks in the updated result. As an example, see how this is
done [in Chromium](https://code.google.com/p/chromium/codesearch#chromium/src/third_party/boringssl/).
## Defines
BoringSSL does not present a lot of configurability in order to reduce the
number of configurations that need to be tested. But there are a couple of
\#defines that you may wish to set:
`OPENSSL_NO_ASM` prevents the use of assembly code (although it's up to you to
ensure that the build system doesn't link it in if you wish to reduce binary
size). This will have a significant performance impact but can be useful if you
wish to use tools like
[AddressSanitizer](http://clang.llvm.org/docs/AddressSanitizer.html) that
interact poorly with assembly code.
`OPENSSL_SMALL` removes some code that is especially large at some performance
cost.
## Symbols
You cannot link multiple versions of BoringSSL or OpenSSL into a single binary
without dealing with symbol conflicts. If you are statically linking multiple
versions together, there's not a lot that can be done because C doesn't have a
module system.
If you are using multiple versions in a single binary, in different shared
objects, ensure you build BoringSSL with `-fvisibility=hidden` and do not
export any of BoringSSL's symbols. This will prevent any collisions with other
verisons that may be included in other shared objects. Note that this requires
that all callers of BoringSSL APIs live in the same shared object as BoringSSL.
If you require that BoringSSL APIs be used across shared object boundaries,
continue to build with `-fvisibility=hidden` but define
`BORINGSSL_SHARED_LIBRARY` in both BoringSSL and consumers. BoringSSL's own
source files (but *not* consumers' source files) must also build with
`BORINGSSL_IMPLEMENTATION` defined. This will export BoringSSL's public symbols
in the resulting shared object while hiding private symbols. However note that,
as with a static link, this precludes dynamically linking with another version
of BoringSSL or OpenSSL.
+1
View File
@@ -25,6 +25,7 @@ There are other files in this directory which might be helpful:
* [PORTING.md](/PORTING.md): how to port OpenSSL-using code to BoringSSL.
* [BUILDING.md](/BUILDING.md): how to build BoringSSL
* [INCORPORATING.md](/INCORPORATING.md): how to incorporate BoringSSL into a project.
* [STYLE.md](/STYLE.md): rules and guidelines for coding style.
* include/openssl: public headers with API documentation in comments. Also [available online](https://commondatastorage.googleapis.com/chromium-boringssl-docs/headers.html).
* [FUZZING.md](/FUZZING.md): information about fuzzing BoringSSL.
+4 -4
View File
@@ -14,10 +14,10 @@ concerned, balance consistency within a module with the benefits of a
given rule. Module-wide deviations on naming should be respected while
integer and return value conventions take precedence over consistency.
Some modules have seen few changes, so they still retain the original
indentation style for now. When editing these, try to retain the
original style. For Emacs, `doc/c-indentation.el` from OpenSSL may be
helpful in this.
Modules from OpenSSL's legacy ASN.1 and X.509 stack are retained for
compatibility and left largely unmodified. To ease importing patches from
upstream, they match OpenSSL's new indentation style. For Emacs,
`doc/openssl-c-indent.el` from OpenSSL may be helpful in this.
## Language
+3 -3
View File
@@ -74,6 +74,7 @@ add_subdirectory(conf)
add_subdirectory(chacha)
add_subdirectory(poly1305)
add_subdirectory(curve25519)
add_subdirectory(newhope)
# Level 1, depends only on 0.*
add_subdirectory(digest)
@@ -116,8 +117,6 @@ add_library(
cpu-arm-linux.c
cpu-intel.c
crypto.c
directory_posix.c
directory_win.c
ex_data.c
mem.c
refcount_c11.c
@@ -166,7 +165,8 @@ add_library(
$<TARGET_OBJECTS:pem>
$<TARGET_OBJECTS:x509>
$<TARGET_OBJECTS:x509v3>
$<TARGET_OBJECTS:pkcs8>
$<TARGET_OBJECTS:pkcs8_lib>
$<TARGET_OBJECTS:newhope>
)
if(NOT MSVC AND NOT ANDROID)
+6 -2
View File
@@ -96,13 +96,17 @@ void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
void AES_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t length,
const AES_KEY *key, uint8_t *ivec, int *num) {
CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
unsigned num_u = (unsigned)(*num);
CRYPTO_ofb128_encrypt(in, out, length, key, ivec, &num_u,
(block128_f)AES_encrypt);
*num = (int)num_u;
}
void AES_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t length,
const AES_KEY *key, uint8_t *ivec, int *num,
int enc) {
CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
unsigned num_u = (unsigned)(*num);
CRYPTO_cfb128_encrypt(in, out, length, key, ivec, &num_u, enc,
(block128_f)AES_encrypt);
*num = (int)num_u;
}
-3
View File
@@ -26,8 +26,6 @@ add_library(
asn1_lib.c
asn1_par.c
asn_pack.c
bio_asn1.c
bio_ndef.c
f_enum.c
f_int.c
f_string.c
@@ -36,7 +34,6 @@ add_library(
tasn_enc.c
tasn_fre.c
tasn_new.c
tasn_prn.c
tasn_typ.c
tasn_utl.c
x_bignum.c
+2 -2
View File
@@ -202,13 +202,13 @@ ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
} else {
if (len != 0) {
if ((ret->length < len) || (ret->data == NULL)) {
if (ret->data != NULL)
OPENSSL_free(ret->data);
s = (unsigned char *)OPENSSL_malloc((int)len + 1);
if (s == NULL) {
i = ERR_R_MALLOC_FAILURE;
goto err;
}
if (ret->data != NULL)
OPENSSL_free(ret->data);
} else
s = ret->data;
memcpy(s, p, (int)len);
+28 -13
View File
@@ -141,6 +141,7 @@ void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
#endif
#define HEADER_SIZE 8
#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024)
static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
{
BUF_MEM *b;
@@ -217,28 +218,42 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
/* suck in c.slen bytes of data */
want = c.slen;
if (want > (len - off)) {
size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE;
want -= (len - off);
if (want > INT_MAX /* BIO_read takes an int length */ ||
len + want < len) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
if (!BUF_MEM_grow_clean(b, len + want)) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
while (want > 0) {
i = BIO_read(in, &(b->data[len]), want);
if (i <= 0) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
/*
* Read content in chunks of increasing size
* so we can return an error for EOF without
* having to allocate the entire content length
* in one go.
*/
size_t chunk = want > chunk_max ? chunk_max : want;
if (!BUF_MEM_grow_clean(b, len + chunk)) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
/*
* This can't overflow because |len+want| didn't
* overflow.
*/
len += i;
want -= i;
want -= chunk;
while (chunk > 0) {
i = BIO_read(in, &(b->data[len]), chunk);
if (i <= 0) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
/*
* This can't overflow because |len+want| didn't
* overflow.
*/
len += i;
chunk -= i;
}
if (chunk_max < INT_MAX/2)
chunk_max *= 2;
}
}
if (off + c.slen < off) {
+1
View File
@@ -247,6 +247,7 @@ int ASN1_STRING_TABLE_add(int nid,
}
tmp->flags = flags | STABLE_FLAGS_MALLOC;
tmp->nid = nid;
tmp->minsize = tmp->maxsize = -1;
new_nid = 1;
} else
tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
-2
View File
@@ -122,9 +122,7 @@ int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
result = a->value.boolean - b->value.boolean;
break;
case V_ASN1_INTEGER:
case V_ASN1_NEG_INTEGER:
case V_ASN1_ENUMERATED:
case V_ASN1_NEG_ENUMERATED:
case V_ASN1_BIT_STRING:
case V_ASN1_OCTET_STRING:
case V_ASN1_SEQUENCE:
+7 -11
View File
@@ -101,7 +101,7 @@ OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_TAG);
OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_TYPE);
static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
int max);
long max);
static void asn1_put_length(unsigned char **pp, int length);
static int _asn1_check_infinite_end(const unsigned char **p, long len)
@@ -173,7 +173,7 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
*ptag = tag;
*pclass = xclass;
if (!asn1_get_length(&p, &inf, plength, (int)max))
if (!asn1_get_length(&p, &inf, plength, max))
goto err;
if (inf && !(ret & V_ASN1_CONSTRUCTED))
@@ -201,14 +201,14 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
}
static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
int max)
long max)
{
const unsigned char *p = *pp;
unsigned long ret = 0;
unsigned int i;
unsigned long i;
if (max-- < 1)
return (0);
return 0;
if (*p == 0x80) {
*inf = 1;
ret = 0;
@@ -217,15 +217,11 @@ static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
*inf = 0;
i = *p & 0x7f;
if (*(p++) & 0x80) {
if (i > sizeof(long))
if (i > sizeof(ret) || max < (long)i)
return 0;
if (max-- == 0)
return (0);
while (i-- > 0) {
ret <<= 8L;
ret |= *(p++);
if (max-- == 0)
return (0);
}
} else
ret = i;
@@ -234,7 +230,7 @@ static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
return 0;
*pp = p;
*rl = (long)ret;
return (1);
return 1;
}
/*
-10
View File
@@ -61,13 +61,3 @@
int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d);
int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d);
/* ASN1 print context structure */
struct asn1_pctx_st {
unsigned long flags;
unsigned long nm_flags;
unsigned long cert_flags;
unsigned long oid_flags;
unsigned long str_flags;
} /* ASN1_PCTX */ ;
-322
View File
@@ -56,328 +56,6 @@
#include <openssl/asn1.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#define ASN1_PARSE_MAXDEPTH 128
static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
int indent);
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
int offset, int depth, int indent, int dump);
static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
int indent)
{
static const char fmt[] = "%-18s";
char str[128];
const char *p;
if (constructed & V_ASN1_CONSTRUCTED)
p = "cons: ";
else
p = "prim: ";
if (BIO_write(bp, p, 6) < 6)
goto err;
BIO_indent(bp, indent, 128);
p = str;
if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
BIO_snprintf(str, sizeof str, "priv [ %d ] ", tag);
else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
BIO_snprintf(str, sizeof str, "cont [ %d ]", tag);
else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
BIO_snprintf(str, sizeof str, "appl [ %d ]", tag);
else if (tag > 30)
BIO_snprintf(str, sizeof str, "<ASN1 %d>", tag);
else
p = ASN1_tag2str(tag);
if (BIO_printf(bp, fmt, p) <= 0)
goto err;
return (1);
err:
return (0);
}
int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
{
return (asn1_parse2(bp, &pp, len, 0, 0, indent, 0));
}
int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent,
int dump)
{
return (asn1_parse2(bp, &pp, len, 0, 0, indent, dump));
}
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
int offset, int depth, int indent, int dump)
{
const unsigned char *p, *ep, *tot, *op, *opp;
long len;
int tag, xclass, ret = 0;
int nl, hl, j, r;
ASN1_OBJECT *o = NULL;
ASN1_OCTET_STRING *os = NULL;
/* ASN1_BMPSTRING *bmp=NULL; */
int dump_indent;
#if 0
dump_indent = indent;
#else
dump_indent = 6; /* Because we know BIO_dump_indent() */
#endif
if (depth > ASN1_PARSE_MAXDEPTH) {
BIO_puts(bp, "BAD RECURSION DEPTH\n");
return 0;
}
p = *pp;
tot = p + length;
op = p - 1;
while ((p < tot) && (op < p)) {
op = p;
j = ASN1_get_object(&p, &len, &tag, &xclass, length);
#ifdef LINT
j = j;
#endif
if (j & 0x80) {
if (BIO_puts(bp, "Error in encoding\n") <= 0)
goto end;
ret = 0;
goto end;
}
hl = (p - op);
length -= hl;
/*
* if j == 0x21 it is a constructed indefinite length object
*/
if (BIO_printf(bp, "%5ld:", (long)offset + (long)(op - *pp))
<= 0)
goto end;
if (j != (V_ASN1_CONSTRUCTED | 1)) {
if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ",
depth, (long)hl, len) <= 0)
goto end;
} else {
if (BIO_printf(bp, "d=%-2d hl=%ld l=inf ", depth, (long)hl) <= 0)
goto end;
}
if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0))
goto end;
if (j & V_ASN1_CONSTRUCTED) {
ep = p + len;
if (BIO_puts(bp, "\n") <= 0)
goto end;
if (len > length) {
BIO_printf(bp, "length is greater than %ld\n", length);
ret = 0;
goto end;
}
if ((j == 0x21) && (len == 0)) {
for (;;) {
r = asn1_parse2(bp, &p, (long)(tot - p),
offset + (p - *pp), depth + 1,
indent, dump);
if (r == 0) {
ret = 0;
goto end;
}
if ((r == 2) || (p >= tot))
break;
}
} else
while (p < ep) {
r = asn1_parse2(bp, &p, (long)len,
offset + (p - *pp), depth + 1,
indent, dump);
if (r == 0) {
ret = 0;
goto end;
}
}
} else if (xclass != 0) {
p += len;
if (BIO_puts(bp, "\n") <= 0)
goto end;
} else {
nl = 0;
if ((tag == V_ASN1_PRINTABLESTRING) ||
(tag == V_ASN1_T61STRING) ||
(tag == V_ASN1_IA5STRING) ||
(tag == V_ASN1_VISIBLESTRING) ||
(tag == V_ASN1_NUMERICSTRING) ||
(tag == V_ASN1_UTF8STRING) ||
(tag == V_ASN1_UTCTIME) || (tag == V_ASN1_GENERALIZEDTIME)) {
if (BIO_puts(bp, ":") <= 0)
goto end;
if ((len > 0) && BIO_write(bp, (const char *)p, (int)len)
!= (int)len)
goto end;
} else if (tag == V_ASN1_OBJECT) {
opp = op;
if (d2i_ASN1_OBJECT(&o, &opp, len + hl) != NULL) {
if (BIO_puts(bp, ":") <= 0)
goto end;
i2a_ASN1_OBJECT(bp, o);
} else {
if (BIO_puts(bp, ":BAD OBJECT") <= 0)
goto end;
}
} else if (tag == V_ASN1_BOOLEAN) {
int ii;
opp = op;
ii = d2i_ASN1_BOOLEAN(NULL, &opp, len + hl);
if (ii < 0) {
if (BIO_puts(bp, "Bad boolean\n") <= 0)
goto end;
}
BIO_printf(bp, ":%d", ii);
} else if (tag == V_ASN1_BMPSTRING) {
/* do the BMP thang */
} else if (tag == V_ASN1_OCTET_STRING) {
int i, printable = 1;
opp = op;
os = d2i_ASN1_OCTET_STRING(NULL, &opp, len + hl);
if (os != NULL && os->length > 0) {
opp = os->data;
/*
* testing whether the octet string is printable
*/
for (i = 0; i < os->length; i++) {
if (((opp[i] < ' ') &&
(opp[i] != '\n') &&
(opp[i] != '\r') &&
(opp[i] != '\t')) || (opp[i] > '~')) {
printable = 0;
break;
}
}
if (printable)
/* printable string */
{
if (BIO_puts(bp, ":") <= 0)
goto end;
if (BIO_write(bp, (const char *)opp, os->length) <= 0)
goto end;
} else if (!dump)
/*
* not printable => print octet string as hex dump
*/
{
if (BIO_puts(bp, "[HEX DUMP]:") <= 0)
goto end;
for (i = 0; i < os->length; i++) {
if (BIO_printf(bp, "%02X", opp[i]) <= 0)
goto end;
}
} else
/* print the normal dump */
{
if (!nl) {
if (BIO_puts(bp, "\n") <= 0)
goto end;
}
if (!BIO_hexdump(bp, opp,
((dump == -1 || dump >
os->length) ? os->length : dump),
dump_indent))
goto end;
nl = 1;
}
}
if (os != NULL) {
M_ASN1_OCTET_STRING_free(os);
os = NULL;
}
} else if (tag == V_ASN1_INTEGER) {
ASN1_INTEGER *bs;
int i;
opp = op;
bs = d2i_ASN1_INTEGER(NULL, &opp, len + hl);
if (bs != NULL) {
if (BIO_puts(bp, ":") <= 0)
goto end;
if (bs->type == V_ASN1_NEG_INTEGER)
if (BIO_puts(bp, "-") <= 0)
goto end;
for (i = 0; i < bs->length; i++) {
if (BIO_printf(bp, "%02X", bs->data[i]) <= 0)
goto end;
}
if (bs->length == 0) {
if (BIO_puts(bp, "00") <= 0)
goto end;
}
} else {
if (BIO_puts(bp, "BAD INTEGER") <= 0)
goto end;
}
M_ASN1_INTEGER_free(bs);
} else if (tag == V_ASN1_ENUMERATED) {
ASN1_ENUMERATED *bs;
int i;
opp = op;
bs = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl);
if (bs != NULL) {
if (BIO_puts(bp, ":") <= 0)
goto end;
if (bs->type == V_ASN1_NEG_ENUMERATED)
if (BIO_puts(bp, "-") <= 0)
goto end;
for (i = 0; i < bs->length; i++) {
if (BIO_printf(bp, "%02X", bs->data[i]) <= 0)
goto end;
}
if (bs->length == 0) {
if (BIO_puts(bp, "00") <= 0)
goto end;
}
} else {
if (BIO_puts(bp, "BAD ENUMERATED") <= 0)
goto end;
}
M_ASN1_ENUMERATED_free(bs);
} else if (len > 0 && dump) {
if (!nl) {
if (BIO_puts(bp, "\n") <= 0)
goto end;
}
if (!BIO_hexdump(bp, p,
((dump == -1 || dump > len) ? len : dump),
dump_indent))
goto end;
nl = 1;
}
if (!nl) {
if (BIO_puts(bp, "\n") <= 0)
goto end;
}
p += len;
if ((tag == V_ASN1_EOC) && (xclass == 0)) {
ret = 2; /* End of sequence */
goto end;
}
}
length -= len;
}
ret = 1;
end:
if (o != NULL)
ASN1_OBJECT_free(o);
if (os != NULL)
M_ASN1_OCTET_STRING_free(os);
*pp = p;
return (ret);
}
const char *ASN1_tag2str(int tag)
{
-477
View File
@@ -1,477 +0,0 @@
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
#include <openssl/asn1.h>
#include <assert.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/mem.h>
/* Must be large enough for biggest tag+length */
#define DEFAULT_ASN1_BUF_SIZE 20
typedef enum {
ASN1_STATE_START,
ASN1_STATE_PRE_COPY,
ASN1_STATE_HEADER,
ASN1_STATE_HEADER_COPY,
ASN1_STATE_DATA_COPY,
ASN1_STATE_POST_COPY,
ASN1_STATE_DONE
} asn1_bio_state_t;
typedef struct BIO_ASN1_EX_FUNCS_st {
asn1_ps_func *ex_func;
asn1_ps_func *ex_free_func;
} BIO_ASN1_EX_FUNCS;
typedef struct BIO_ASN1_BUF_CTX_t {
/* Internal state */
asn1_bio_state_t state;
/* Internal buffer */
unsigned char *buf;
/* Size of buffer */
int bufsize;
/* Current position in buffer */
int bufpos;
/* Current buffer length */
int buflen;
/* Amount of data to copy */
int copylen;
/* Class and tag to use */
int asn1_class, asn1_tag;
asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
/* Extra buffer for prefix and suffix data */
unsigned char *ex_buf;
int ex_len;
int ex_pos;
void *ex_arg;
} BIO_ASN1_BUF_CTX;
static int asn1_bio_write(BIO *h, const char *buf, int num);
static int asn1_bio_read(BIO *h, char *buf, int size);
static int asn1_bio_puts(BIO *h, const char *str);
static int asn1_bio_gets(BIO *h, char *str, int size);
static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int asn1_bio_new(BIO *h);
static int asn1_bio_free(BIO *data);
static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb fp);
static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
asn1_ps_func *cleanup, asn1_bio_state_t next);
static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
asn1_ps_func *setup,
asn1_bio_state_t ex_state,
asn1_bio_state_t other_state);
static const BIO_METHOD methods_asn1 = {
BIO_TYPE_ASN1,
"asn1",
asn1_bio_write,
asn1_bio_read,
asn1_bio_puts,
asn1_bio_gets,
asn1_bio_ctrl,
asn1_bio_new,
asn1_bio_free,
asn1_bio_callback_ctrl,
};
const BIO_METHOD *BIO_f_asn1(void)
{
return (&methods_asn1);
}
static int asn1_bio_new(BIO *b)
{
BIO_ASN1_BUF_CTX *ctx;
ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX));
if (!ctx)
return 0;
if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) {
OPENSSL_free(ctx);
return 0;
}
b->init = 1;
b->ptr = (char *)ctx;
b->flags = 0;
return 1;
}
static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
{
ctx->buf = OPENSSL_malloc(size);
if (!ctx->buf)
return 0;
ctx->bufsize = size;
ctx->bufpos = 0;
ctx->buflen = 0;
ctx->copylen = 0;
ctx->asn1_class = V_ASN1_UNIVERSAL;
ctx->asn1_tag = V_ASN1_OCTET_STRING;
ctx->ex_buf = 0;
ctx->ex_pos = 0;
ctx->ex_len = 0;
ctx->state = ASN1_STATE_START;
return 1;
}
static int asn1_bio_free(BIO *b)
{
BIO_ASN1_BUF_CTX *ctx;
ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
if (ctx == NULL)
return 0;
if (ctx->buf)
OPENSSL_free(ctx->buf);
OPENSSL_free(ctx);
b->init = 0;
b->ptr = NULL;
b->flags = 0;
return 1;
}
static int asn1_bio_write(BIO *b, const char *in, int inl)
{
BIO_ASN1_BUF_CTX *ctx;
int wrmax, wrlen, ret;
unsigned char *p;
if (!in || (inl < 0) || (b->next_bio == NULL))
return 0;
ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
if (ctx == NULL)
return 0;
wrlen = 0;
ret = -1;
for (;;) {
switch (ctx->state) {
/* Setup prefix data, call it */
case ASN1_STATE_START:
if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
return 0;
break;
/* Copy any pre data first */
case ASN1_STATE_PRE_COPY:
ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
ASN1_STATE_HEADER);
if (ret <= 0)
goto done;
break;
case ASN1_STATE_HEADER:
ctx->buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
assert(ctx->buflen <= ctx->bufsize);
p = ctx->buf;
ASN1_put_object(&p, 0, inl, ctx->asn1_tag, ctx->asn1_class);
ctx->copylen = inl;
ctx->state = ASN1_STATE_HEADER_COPY;
break;
case ASN1_STATE_HEADER_COPY:
ret = BIO_write(b->next_bio, ctx->buf + ctx->bufpos, ctx->buflen);
if (ret <= 0)
goto done;
ctx->buflen -= ret;
if (ctx->buflen)
ctx->bufpos += ret;
else {
ctx->bufpos = 0;
ctx->state = ASN1_STATE_DATA_COPY;
}
break;
case ASN1_STATE_DATA_COPY:
if (inl > ctx->copylen)
wrmax = ctx->copylen;
else
wrmax = inl;
ret = BIO_write(b->next_bio, in, wrmax);
if (ret <= 0)
break;
wrlen += ret;
ctx->copylen -= ret;
in += ret;
inl -= ret;
if (ctx->copylen == 0)
ctx->state = ASN1_STATE_HEADER;
if (inl == 0)
goto done;
break;
default:
BIO_clear_retry_flags(b);
return 0;
}
}
done:
BIO_clear_retry_flags(b);
BIO_copy_next_retry(b);
return (wrlen > 0) ? wrlen : ret;
}
static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
asn1_ps_func *cleanup, asn1_bio_state_t next)
{
int ret;
if (ctx->ex_len <= 0)
return 1;
for (;;) {
ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos, ctx->ex_len);
if (ret <= 0)
break;
ctx->ex_len -= ret;
if (ctx->ex_len > 0)
ctx->ex_pos += ret;
else {
if (cleanup)
cleanup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg);
ctx->state = next;
ctx->ex_pos = 0;
break;
}
}
return ret;
}
static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
asn1_ps_func *setup,
asn1_bio_state_t ex_state,
asn1_bio_state_t other_state)
{
if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) {
BIO_clear_retry_flags(b);
return 0;
}
if (ctx->ex_len > 0)
ctx->state = ex_state;
else
ctx->state = other_state;
return 1;
}
static int asn1_bio_read(BIO *b, char *in, int inl)
{
if (!b->next_bio)
return 0;
return BIO_read(b->next_bio, in, inl);
}
static int asn1_bio_puts(BIO *b, const char *str)
{
return asn1_bio_write(b, str, strlen(str));
}
static int asn1_bio_gets(BIO *b, char *str, int size)
{
if (!b->next_bio)
return 0;
return BIO_gets(b->next_bio, str, size);
}
static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb fp)
{
if (b->next_bio == NULL)
return (0);
return BIO_callback_ctrl(b->next_bio, cmd, fp);
}
static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
{
BIO_ASN1_BUF_CTX *ctx;
BIO_ASN1_EX_FUNCS *ex_func;
long ret = 1;
ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
if (ctx == NULL)
return 0;
switch (cmd) {
case BIO_C_SET_PREFIX:
ex_func = arg2;
ctx->prefix = ex_func->ex_func;
ctx->prefix_free = ex_func->ex_free_func;
break;
case BIO_C_GET_PREFIX:
ex_func = arg2;
ex_func->ex_func = ctx->prefix;
ex_func->ex_free_func = ctx->prefix_free;
break;
case BIO_C_SET_SUFFIX:
ex_func = arg2;
ctx->suffix = ex_func->ex_func;
ctx->suffix_free = ex_func->ex_free_func;
break;
case BIO_C_GET_SUFFIX:
ex_func = arg2;
ex_func->ex_func = ctx->suffix;
ex_func->ex_free_func = ctx->suffix_free;
break;
case BIO_C_SET_EX_ARG:
ctx->ex_arg = arg2;
break;
case BIO_C_GET_EX_ARG:
*(void **)arg2 = ctx->ex_arg;
break;
case BIO_CTRL_FLUSH:
if (!b->next_bio)
return 0;
/* Call post function if possible */
if (ctx->state == ASN1_STATE_HEADER) {
if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
return 0;
}
if (ctx->state == ASN1_STATE_POST_COPY) {
ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
ASN1_STATE_DONE);
if (ret <= 0)
return ret;
}
if (ctx->state == ASN1_STATE_DONE)
return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
else {
BIO_clear_retry_flags(b);
return 0;
}
break;
default:
if (!b->next_bio)
return 0;
return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
}
return ret;
}
static int asn1_bio_set_ex(BIO *b, int cmd,
asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
{
BIO_ASN1_EX_FUNCS extmp;
extmp.ex_func = ex_func;
extmp.ex_free_func = ex_free_func;
return BIO_ctrl(b, cmd, 0, &extmp);
}
static int asn1_bio_get_ex(BIO *b, int cmd,
asn1_ps_func **ex_func,
asn1_ps_func **ex_free_func)
{
BIO_ASN1_EX_FUNCS extmp;
int ret;
ret = BIO_ctrl(b, cmd, 0, &extmp);
if (ret > 0) {
*ex_func = extmp.ex_func;
*ex_free_func = extmp.ex_free_func;
}
return ret;
}
int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
asn1_ps_func *prefix_free)
{
return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
}
int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
asn1_ps_func **pprefix_free)
{
return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
}
int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
asn1_ps_func *suffix_free)
{
return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
}
int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
asn1_ps_func **psuffix_free)
{
return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
}
-251
View File
@@ -1,251 +0,0 @@
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
#include <openssl/asn1.h>
#include <assert.h>
#include <openssl/asn1t.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/mem.h>
/* Experimental NDEF ASN1 BIO support routines */
/*
* The usage is quite simple, initialize an ASN1 structure, get a BIO from it
* then any data written through the BIO will end up translated to
* approptiate format on the fly. The data is streamed out and does *not*
* need to be all held in memory at once. When the BIO is flushed the output
* is finalized and any signatures etc written out. The BIO is a 'proper'
* BIO and can handle non blocking I/O correctly. The usage is simple. The
* implementation is *not*...
*/
/* BIO support data stored in the ASN1 BIO ex_arg */
typedef struct ndef_aux_st {
/* ASN1 structure this BIO refers to */
ASN1_VALUE *val;
const ASN1_ITEM *it;
/* Top of the BIO chain */
BIO *ndef_bio;
/* Output BIO */
BIO *out;
/* Boundary where content is inserted */
unsigned char **boundary;
/* DER buffer start */
unsigned char *derbuf;
} NDEF_SUPPORT;
static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
void *parg);
static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
void *parg);
BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
{
NDEF_SUPPORT *ndef_aux = NULL;
BIO *asn_bio = NULL;
const ASN1_AUX *aux = it->funcs;
ASN1_STREAM_ARG sarg;
if (!aux || !aux->asn1_cb) {
OPENSSL_PUT_ERROR(ASN1, ASN1_R_STREAMING_NOT_SUPPORTED);
return NULL;
}
ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
asn_bio = BIO_new(BIO_f_asn1());
/* ASN1 bio needs to be next to output BIO */
out = BIO_push(asn_bio, out);
if (!ndef_aux || !asn_bio || !out)
goto err;
BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
/*
* Now let callback prepend any digest, cipher etc BIOs ASN1 structure
* needs.
*/
sarg.out = out;
sarg.ndef_bio = NULL;
sarg.boundary = NULL;
if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
goto err;
ndef_aux->val = val;
ndef_aux->it = it;
ndef_aux->ndef_bio = sarg.ndef_bio;
ndef_aux->boundary = sarg.boundary;
ndef_aux->out = out;
BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
return sarg.ndef_bio;
err:
if (asn_bio)
BIO_free(asn_bio);
if (ndef_aux)
OPENSSL_free(ndef_aux);
return NULL;
}
static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
{
NDEF_SUPPORT *ndef_aux;
unsigned char *p;
int derlen;
if (!parg)
return 0;
ndef_aux = *(NDEF_SUPPORT **)parg;
derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
p = OPENSSL_malloc(derlen);
if (p == NULL)
return 0;
ndef_aux->derbuf = p;
*pbuf = p;
derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
if (!*ndef_aux->boundary)
return 0;
*plen = *ndef_aux->boundary - *pbuf;
return 1;
}
static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
void *parg)
{
NDEF_SUPPORT *ndef_aux;
if (!parg)
return 0;
ndef_aux = *(NDEF_SUPPORT **)parg;
if (ndef_aux->derbuf)
OPENSSL_free(ndef_aux->derbuf);
ndef_aux->derbuf = NULL;
*pbuf = NULL;
*plen = 0;
return 1;
}
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
void *parg)
{
NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
if (!ndef_prefix_free(b, pbuf, plen, parg))
return 0;
OPENSSL_free(*pndef_aux);
*pndef_aux = NULL;
return 1;
}
static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
{
NDEF_SUPPORT *ndef_aux;
unsigned char *p;
int derlen;
const ASN1_AUX *aux;
ASN1_STREAM_ARG sarg;
if (!parg)
return 0;
ndef_aux = *(NDEF_SUPPORT **)parg;
aux = ndef_aux->it->funcs;
/* Finalize structures */
sarg.ndef_bio = ndef_aux->ndef_bio;
sarg.out = ndef_aux->out;
sarg.boundary = ndef_aux->boundary;
if (aux->asn1_cb(ASN1_OP_STREAM_POST,
&ndef_aux->val, ndef_aux->it, &sarg) <= 0)
return 0;
derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
p = OPENSSL_malloc(derlen);
if (p == NULL)
return 0;
ndef_aux->derbuf = p;
*pbuf = p;
derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
if (!*ndef_aux->boundary)
return 0;
*pbuf = *ndef_aux->boundary;
*plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
return 1;
}
-2
View File
@@ -894,9 +894,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
break;
case V_ASN1_INTEGER:
case V_ASN1_NEG_INTEGER:
case V_ASN1_ENUMERATED:
case V_ASN1_NEG_ENUMERATED:
tint = (ASN1_INTEGER **)pval;
if (!c2i_ASN1_INTEGER(tint, &cont, len))
goto err;
-2
View File
@@ -609,9 +609,7 @@ int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype,
break;
case V_ASN1_INTEGER:
case V_ASN1_NEG_INTEGER:
case V_ASN1_ENUMERATED:
case V_ASN1_NEG_ENUMERATED:
/*
* These are all have the same content format as ASN1_INTEGER
*/
-596
View File
@@ -1,596 +0,0 @@
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
* All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
*
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
*
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* "This product includes cryptographic software written by
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
* 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
*
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
#include <openssl/asn1.h>
#include <time.h>
#include <openssl/asn1t.h>
#include <openssl/err.h>
#include <openssl/obj.h>
#include <openssl/mem.h>
#include "asn1_locl.h"
/*
* Print routines.
*/
/* ASN1_PCTX routines */
static ASN1_PCTX default_pctx = {
ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */
0, /* nm_flags */
0, /* cert_flags */
0, /* oid_flags */
0 /* str_flags */
};
ASN1_PCTX *ASN1_PCTX_new(void)
{
ASN1_PCTX *ret;
ret = OPENSSL_malloc(sizeof(ASN1_PCTX));
if (ret == NULL) {
OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->flags = 0;
ret->nm_flags = 0;
ret->cert_flags = 0;
ret->oid_flags = 0;
ret->str_flags = 0;
return ret;
}
void ASN1_PCTX_free(ASN1_PCTX *p)
{
OPENSSL_free(p);
}
unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p)
{
return p->flags;
}
void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags)
{
p->flags = flags;
}
unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p)
{
return p->nm_flags;
}
void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags)
{
p->nm_flags = flags;
}
unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p)
{
return p->cert_flags;
}
void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags)
{
p->cert_flags = flags;
}
unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p)
{
return p->oid_flags;
}
void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags)
{
p->oid_flags = flags;
}
unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p)
{
return p->str_flags;
}
void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags)
{
p->str_flags = flags;
}
/* Main print routines */
static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
const ASN1_ITEM *it,
const char *fname, const char *sname,
int nohdr, const ASN1_PCTX *pctx);
int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx);
static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
const ASN1_ITEM *it, int indent,
const char *fname, const char *sname,
const ASN1_PCTX *pctx);
static int asn1_print_fsname(BIO *out, int indent,
const char *fname, const char *sname,
const ASN1_PCTX *pctx);
int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent,
const ASN1_ITEM *it, const ASN1_PCTX *pctx)
{
const char *sname;
if (pctx == NULL)
pctx = &default_pctx;
if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
sname = NULL;
else
sname = it->sname;
return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname, 0, pctx);
}
static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
const ASN1_ITEM *it,
const char *fname, const char *sname,
int nohdr, const ASN1_PCTX *pctx)
{
const ASN1_TEMPLATE *tt;
const ASN1_EXTERN_FUNCS *ef;
ASN1_VALUE **tmpfld;
const ASN1_AUX *aux = it->funcs;
ASN1_aux_cb *asn1_cb;
ASN1_PRINT_ARG parg;
int i;
if (aux && aux->asn1_cb) {
parg.out = out;
parg.indent = indent;
parg.pctx = pctx;
asn1_cb = aux->asn1_cb;
} else
asn1_cb = 0;
if (*fld == NULL) {
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) {
if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
return 0;
if (BIO_puts(out, "<ABSENT>\n") <= 0)
return 0;
}
return 1;
}
switch (it->itype) {
case ASN1_ITYPE_PRIMITIVE:
if (it->templates) {
if (!asn1_template_print_ctx(out, fld, indent,
it->templates, pctx))
return 0;
break;
}
/* fall thru */
case ASN1_ITYPE_MSTRING:
if (!asn1_primitive_print(out, fld, it, indent, fname, sname, pctx))
return 0;
break;
case ASN1_ITYPE_EXTERN:
if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
return 0;
/* Use new style print routine if possible */
ef = it->funcs;
if (ef && ef->asn1_ex_print) {
i = ef->asn1_ex_print(out, fld, indent, "", pctx);
if (!i)
return 0;
if ((i == 2) && (BIO_puts(out, "\n") <= 0))
return 0;
return 1;
} else if (sname &&
BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0)
return 0;
break;
case ASN1_ITYPE_CHOICE:
#if 0
if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
return 0;
#endif
/* CHOICE type, get selector */
i = asn1_get_choice_selector(fld, it);
/* This should never happen... */
if ((i < 0) || (i >= it->tcount)) {
if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0)
return 0;
return 1;
}
tt = it->templates + i;
tmpfld = asn1_get_field_ptr(fld, tt);
if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx))
return 0;
break;
case ASN1_ITYPE_SEQUENCE:
case ASN1_ITYPE_NDEF_SEQUENCE:
if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
return 0;
if (fname || sname) {
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
if (BIO_puts(out, " {\n") <= 0)
return 0;
} else {
if (BIO_puts(out, "\n") <= 0)
return 0;
}
}
if (asn1_cb) {
i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg);
if (i == 0)
return 0;
if (i == 2)
return 1;
}
/* Print each field entry */
for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) {
const ASN1_TEMPLATE *seqtt;
seqtt = asn1_do_adb(fld, tt, 1);
if (!seqtt)
return 0;
tmpfld = asn1_get_field_ptr(fld, seqtt);
if (!asn1_template_print_ctx(out, tmpfld,
indent + 2, seqtt, pctx))
return 0;
}
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
if (BIO_printf(out, "%*s}\n", indent, "") < 0)
return 0;
}
if (asn1_cb) {
i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg);
if (i == 0)
return 0;
}
break;
default:
BIO_printf(out, "Unprocessed type %d\n", it->itype);
return 0;
}
return 1;
}
int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx)
{
int flags;
size_t i;
const char *sname, *fname;
flags = tt->flags;
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME)
sname = ASN1_ITEM_ptr(tt->item)->sname;
else
sname = NULL;
if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
fname = NULL;
else
fname = tt->field_name;
if (flags & ASN1_TFLG_SK_MASK) {
const char *tname;
ASN1_VALUE *skitem;
STACK_OF(ASN1_VALUE) *stack;
/* SET OF, SEQUENCE OF */
if (fname) {
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) {
if (flags & ASN1_TFLG_SET_OF)
tname = "SET";
else
tname = "SEQUENCE";
if (BIO_printf(out, "%*s%s OF %s {\n",
indent, "", tname, tt->field_name) <= 0)
return 0;
} else if (BIO_printf(out, "%*s%s:\n", indent, "", fname) <= 0)
return 0;
}
stack = (STACK_OF(ASN1_VALUE) *)*fld;
for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) {
if ((i > 0) && (BIO_puts(out, "\n") <= 0))
return 0;
skitem = sk_ASN1_VALUE_value(stack, i);
if (!asn1_item_print_ctx(out, &skitem, indent + 2,
ASN1_ITEM_ptr(tt->item), NULL, NULL, 1,
pctx))
return 0;
}
if (!i && BIO_printf(out, "%*s<EMPTY>\n", indent + 2, "") <= 0)
return 0;
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) {
if (BIO_printf(out, "%*s}\n", indent, "") <= 0)
return 0;
}
return 1;
}
return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item),
fname, sname, 0, pctx);
}
static int asn1_print_fsname(BIO *out, int indent,
const char *fname, const char *sname,
const ASN1_PCTX *pctx)
{
static char spaces[] = " ";
const int nspaces = sizeof(spaces) - 1;
#if 0
if (!sname && !fname)
return 1;
#endif
while (indent > nspaces) {
if (BIO_write(out, spaces, nspaces) != nspaces)
return 0;
indent -= nspaces;
}
if (BIO_write(out, spaces, indent) != indent)
return 0;
if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME)
sname = NULL;
if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME)
fname = NULL;
if (!sname && !fname)
return 1;
if (fname) {
if (BIO_puts(out, fname) <= 0)
return 0;
}
if (sname) {
if (fname) {
if (BIO_printf(out, " (%s)", sname) <= 0)
return 0;
} else {
if (BIO_puts(out, sname) <= 0)
return 0;
}
}
if (BIO_write(out, ": ", 2) != 2)
return 0;
return 1;
}
static int asn1_print_boolean_ctx(BIO *out, int boolval,
const ASN1_PCTX *pctx)
{
const char *str;
switch (boolval) {
case -1:
str = "BOOL ABSENT";
break;
case 0:
str = "FALSE";
break;
default:
str = "TRUE";
break;
}
if (BIO_puts(out, str) <= 0)
return 0;
return 1;
}
static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str,
const ASN1_PCTX *pctx)
{
BIGNUM *bn = NULL;
char *s = NULL;
int ret = 1;
bn = ASN1_INTEGER_to_BN(str, NULL);
if (bn == NULL) {
return 0;
}
s = BN_bn2dec(bn);
BN_free(bn);
if (s == NULL) {
return 0;
}
if (BIO_puts(out, s) <= 0) {
ret = 0;
}
OPENSSL_free(s);
return ret;
}
static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid,
const ASN1_PCTX *pctx)
{
char objbuf[80];
const char *ln;
ln = OBJ_nid2ln(OBJ_obj2nid(oid));
if (!ln)
ln = "";
OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1);
if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0)
return 0;
return 1;
}
static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent,
const ASN1_PCTX *pctx)
{
if (str->type == V_ASN1_BIT_STRING) {
if (BIO_printf(out, " (%ld unused bits)\n", str->flags & 0x7) <= 0)
return 0;
} else if (BIO_puts(out, "\n") <= 0)
return 0;
if (str->length > 0
&& !BIO_hexdump(out, str->data, str->length, indent + 2)) {
return 0;
}
return 1;
}
static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
const ASN1_ITEM *it, int indent,
const char *fname, const char *sname,
const ASN1_PCTX *pctx)
{
long utype;
ASN1_STRING *str;
int ret = 1, needlf = 1;
const char *pname;
const ASN1_PRIMITIVE_FUNCS *pf;
pf = it->funcs;
if (!asn1_print_fsname(out, indent, fname, sname, pctx))
return 0;
if (pf && pf->prim_print)
return pf->prim_print(out, fld, it, indent, pctx);
str = (ASN1_STRING *)*fld;
if (it->itype == ASN1_ITYPE_MSTRING)
utype = str->type & ~V_ASN1_NEG;
else
utype = it->utype;
if (utype == V_ASN1_ANY) {
ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
utype = atype->type;
fld = &atype->value.asn1_value;
str = (ASN1_STRING *)*fld;
if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE)
pname = NULL;
else
pname = ASN1_tag2str(utype);
} else {
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE)
pname = ASN1_tag2str(utype);
else
pname = NULL;
}
if (utype == V_ASN1_NULL) {
if (BIO_puts(out, "NULL\n") <= 0)
return 0;
return 1;
}
if (pname) {
if (BIO_puts(out, pname) <= 0)
return 0;
if (BIO_puts(out, ":") <= 0)
return 0;
}
switch (utype) {
case V_ASN1_BOOLEAN:
{
int boolval = *(int *)fld;
if (boolval == -1)
boolval = it->size;
ret = asn1_print_boolean_ctx(out, boolval, pctx);
}
break;
case V_ASN1_INTEGER:
case V_ASN1_ENUMERATED:
ret = asn1_print_integer_ctx(out, str, pctx);
break;
case V_ASN1_UTCTIME:
ret = ASN1_UTCTIME_print(out, str);
break;
case V_ASN1_GENERALIZEDTIME:
ret = ASN1_GENERALIZEDTIME_print(out, str);
break;
case V_ASN1_OBJECT:
ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx);
break;
case V_ASN1_OCTET_STRING:
case V_ASN1_BIT_STRING:
ret = asn1_print_obstring_ctx(out, str, indent, pctx);
needlf = 0;
break;
case V_ASN1_SEQUENCE:
case V_ASN1_SET:
case V_ASN1_OTHER:
if (BIO_puts(out, "\n") <= 0)
return 0;
if (ASN1_parse_dump(out, str->data, str->length, indent, 0) <= 0)
ret = 0;
needlf = 0;
break;
default:
ret = ASN1_STRING_print_ex(out, str, pctx->str_flags);
}
if (!ret)
return 0;
if (needlf && BIO_puts(out, "\n") <= 0)
return 0;
return 1;
}
+263 -303
View File
@@ -60,118 +60,119 @@
#include <limits.h>
#include <string.h>
#include <openssl/type_check.h>
/* Encoding. */
static const unsigned char data_bin2ascii[65] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
#define conv_bin2ascii(a) (data_bin2ascii[(a) & 0x3f])
/* 64 char lines
* pad input with 0
* left over chars are set to =
* 1 byte => xx==
* 2 bytes => xxx=
* 3 bytes => xxxx
*/
#define BIN_PER_LINE (64/4*3)
#define CHUNKS_PER_LINE (64/4)
#define CHAR_PER_LINE (64+1)
OPENSSL_COMPILE_ASSERT(sizeof(((EVP_ENCODE_CTX *)(NULL))->data) % 3 == 0,
data_length_must_be_multiple_of_base64_chunk_size);
/* 0xF0 is a EOLN
* 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
* 0xF2 is EOF
* 0xE0 is ignore at start of line.
* 0xFF is error */
#define B64_EOLN 0xF0
#define B64_CR 0xF1
#define B64_EOF 0xF2
#define B64_WS 0xE0
#define B64_ERROR 0xFF
#define B64_NOT_BASE64(a) (((a) | 0x13) == 0xF3)
static const uint8_t data_ascii2bin[128] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xF0, 0xFF,
0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12,
0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24,
0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
};
static uint8_t conv_ascii2bin(uint8_t a) {
if (a >= 128) {
return 0xFF;
int EVP_EncodedLength(size_t *out_len, size_t len) {
if (len + 2 < len) {
return 0;
}
return data_ascii2bin[a];
len += 2;
len /= 3;
if (((len << 2) >> 2) != len) {
return 0;
}
len <<= 2;
if (len + 1 < len) {
return 0;
}
len++;
*out_len = len;
return 1;
}
void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) {
ctx->length = 48;
ctx->num = 0;
ctx->line_num = 0;
memset(ctx, 0, sizeof(EVP_ENCODE_CTX));
}
void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
const uint8_t *in, size_t in_len) {
unsigned i, j;
unsigned total = 0;
size_t total = 0;
*out_len = 0;
if (in_len == 0) {
return;
}
assert(ctx->length <= sizeof(ctx->enc_data));
assert(ctx->data_used < sizeof(ctx->data));
if (ctx->num + in_len < ctx->length) {
memcpy(&ctx->enc_data[ctx->num], in, in_len);
ctx->num += in_len;
if (sizeof(ctx->data) - ctx->data_used > in_len) {
memcpy(&ctx->data[ctx->data_used], in, in_len);
ctx->data_used += in_len;
return;
}
if (ctx->num != 0) {
i = ctx->length - ctx->num;
memcpy(&ctx->enc_data[ctx->num], in, i);
in += i;
in_len -= i;
j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length);
ctx->num = 0;
out += j;
if (ctx->data_used != 0) {
const size_t todo = sizeof(ctx->data) - ctx->data_used;
memcpy(&ctx->data[ctx->data_used], in, todo);
in += todo;
in_len -= todo;
size_t encoded = EVP_EncodeBlock(out, ctx->data, sizeof(ctx->data));
ctx->data_used = 0;
out += encoded;
*(out++) = '\n';
*out = '\0';
total = j + 1;
total = encoded + 1;
}
while (in_len >= ctx->length) {
j = EVP_EncodeBlock(out, in, ctx->length);
in += ctx->length;
in_len -= ctx->length;
out += j;
while (in_len >= sizeof(ctx->data)) {
size_t encoded = EVP_EncodeBlock(out, in, sizeof(ctx->data));
in += sizeof(ctx->data);
in_len -= sizeof(ctx->data);
out += encoded;
*(out++) = '\n';
*out = '\0';
total += j + 1;
if (total + encoded + 1 < total) {
*out_len = 0;
return;
}
total += encoded + 1;
}
if (in_len != 0) {
memcpy(&ctx->enc_data[0], in, in_len);
memcpy(ctx->data, in, in_len);
}
ctx->data_used = in_len;
if (total > INT_MAX) {
/* We cannot signal an error, but we can at least avoid making *out_len
* negative. */
total = 0;
}
ctx->num = in_len;
*out_len = total;
}
void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) {
unsigned ret = 0;
if (ctx->num != 0) {
ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num);
out[ret++] = '\n';
out[ret] = '\0';
ctx->num = 0;
if (ctx->data_used == 0) {
*out_len = 0;
return;
}
*out_len = ret;
size_t encoded = EVP_EncodeBlock(out, ctx->data, ctx->data_used);
out[encoded++] = '\n';
out[encoded] = '\0';
ctx->data_used = 0;
*out_len = encoded;
}
size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
@@ -206,246 +207,223 @@ size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
return ret;
}
/* Decoding. */
int EVP_DecodedLength(size_t *out_len, size_t len) {
if (len % 4 != 0) {
return 0;
}
*out_len = (len / 4) * 3;
return 1;
}
void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) {
memset(ctx, 0, sizeof(EVP_ENCODE_CTX));
}
/* kBase64ASCIIToBinData maps characters (c < 128) to their base64 value, or
* else 0xff if they are invalid. As a special case, the padding character
* ('=') is mapped to zero. */
static const uint8_t kBase64ASCIIToBinData[128] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff,
0xff, 0x00, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24,
0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff,
};
static uint8_t base64_ascii_to_bin(uint8_t a) {
if (a >= 128) {
return 0xFF;
}
return kBase64ASCIIToBinData[a];
}
/* base64_decode_quad decodes a single “quad” (i.e. four characters) of base64
* data and writes up to three bytes to |out|. It sets |*out_num_bytes| to the
* number of bytes written, which will be less than three if the quad ended
* with padding. It returns one on success or zero on error. */
static int base64_decode_quad(uint8_t *out, size_t *out_num_bytes,
const uint8_t *in) {
const uint8_t a = base64_ascii_to_bin(in[0]);
const uint8_t b = base64_ascii_to_bin(in[1]);
const uint8_t c = base64_ascii_to_bin(in[2]);
const uint8_t d = base64_ascii_to_bin(in[3]);
if (a == 0xff || b == 0xff || c == 0xff || d == 0xff) {
return 0;
}
const uint32_t v = ((uint32_t)a) << 18 | ((uint32_t)b) << 12 |
((uint32_t)c) << 6 | (uint32_t)d;
const unsigned padding_pattern = (in[0] == '=') << 3 |
(in[1] == '=') << 2 |
(in[2] == '=') << 1 |
(in[3] == '=');
switch (padding_pattern) {
case 0:
/* The common case of no padding. */
*out_num_bytes = 3;
out[0] = v >> 16;
out[1] = v >> 8;
out[2] = v;
break;
case 1: /* xxx= */
*out_num_bytes = 2;
out[0] = v >> 16;
out[1] = v >> 8;
break;
case 3: /* xx== */
*out_num_bytes = 1;
out[0] = v >> 16;
break;
default:
return 0;
}
return 1;
}
int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
const uint8_t *in, size_t in_len) {
*out_len = 0;
if (ctx->error_encountered) {
return -1;
}
size_t bytes_out = 0, i;
for (i = 0; i < in_len; i++) {
const char c = in[i];
switch (c) {
case ' ':
case '\t':
case '\r':
case '\n':
continue;
}
if (base64_ascii_to_bin(c) == 0xff || ctx->eof_seen) {
ctx->error_encountered = 1;
return -1;
}
ctx->data[ctx->data_used++] = c;
if (ctx->data_used == 4) {
size_t num_bytes_resulting;
if (!base64_decode_quad(out, &num_bytes_resulting, ctx->data)) {
ctx->error_encountered = 1;
return -1;
}
ctx->data_used = 0;
bytes_out += num_bytes_resulting;
out += num_bytes_resulting;
if (num_bytes_resulting < 3) {
ctx->eof_seen = 1;
}
}
}
if (bytes_out > INT_MAX) {
ctx->error_encountered = 1;
*out_len = 0;
return -1;
}
*out_len = bytes_out;
if (ctx->eof_seen) {
return 0;
}
return 1;
}
int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) {
*out_len = 0;
if (ctx->error_encountered || ctx->data_used != 0) {
return -1;
}
return 1;
}
int EVP_DecodeBase64(uint8_t *out, size_t *out_len, size_t max_out,
const uint8_t *in, size_t in_len) {
uint8_t a, b, c, d;
size_t pad_len = 0, len = 0, max_len, i;
uint32_t l;
*out_len = 0;
if (!EVP_DecodedLength(&max_len, in_len) || max_out < max_len) {
if (in_len % 4 != 0) {
return 0;
}
size_t max_len;
if (!EVP_DecodedLength(&max_len, in_len) ||
max_out < max_len) {
return 0;
}
size_t i, bytes_out = 0;
for (i = 0; i < in_len; i += 4) {
a = conv_ascii2bin(*(in++));
b = conv_ascii2bin(*(in++));
if (i + 4 == in_len && in[1] == '=') {
if (in[0] == '=') {
pad_len = 2;
} else {
pad_len = 1;
}
}
if (pad_len < 2) {
c = conv_ascii2bin(*(in++));
} else {
c = 0;
}
if (pad_len < 1) {
d = conv_ascii2bin(*(in++));
} else {
d = 0;
}
if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80)) {
size_t num_bytes_resulting;
if (!base64_decode_quad(out, &num_bytes_resulting, &in[i])) {
return 0;
}
l = ((((uint32_t)a) << 18L) | (((uint32_t)b) << 12L) |
(((uint32_t)c) << 6L) | (((uint32_t)d)));
*(out++) = (uint8_t)(l >> 16L) & 0xff;
if (pad_len < 2) {
*(out++) = (uint8_t)(l >> 8L) & 0xff;
bytes_out += num_bytes_resulting;
out += num_bytes_resulting;
if (num_bytes_resulting != 3 && i != in_len - 4) {
return 0;
}
if (pad_len < 1) {
*(out++) = (uint8_t)(l) & 0xff;
}
len += 3 - pad_len;
}
*out_len = len;
*out_len = bytes_out;
return 1;
}
void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) {
ctx->length = 30;
ctx->num = 0;
ctx->line_num = 0;
ctx->expect_nl = 0;
}
int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
const uint8_t *in, size_t in_len) {
int seof = -1, eof = 0, rv = -1, v, tmp, exp_nl;
uint8_t *d;
unsigned i, n, ln, ret = 0;
n = ctx->num;
d = ctx->enc_data;
ln = ctx->line_num;
exp_nl = ctx->expect_nl;
/* last line of input. */
if (in_len == 0 || (n == 0 && conv_ascii2bin(in[0]) == B64_EOF)) {
rv = 0;
goto end;
}
/* We parse the input data */
for (i = 0; i < in_len; i++) {
/* If the current line is > 80 characters, scream alot */
if (ln >= 80) {
rv = -1;
goto end;
}
/* Get char and put it into the buffer */
tmp = *(in++);
v = conv_ascii2bin(tmp);
/* only save the good data :-) */
if (!B64_NOT_BASE64(v)) {
assert(n < sizeof(ctx->enc_data));
d[n++] = tmp;
ln++;
} else if (v == B64_ERROR) {
rv = -1;
goto end;
}
/* have we seen a '=' which is 'definitly' the last
* input line. seof will point to the character that
* holds it. and eof will hold how many characters to
* chop off. */
if (tmp == '=') {
if (seof == -1) {
seof = n;
}
eof++;
if (eof > 2) {
/* There are, at most, two equals signs at the end of base64 data. */
rv = -1;
goto end;
}
}
if (v == B64_CR) {
ln = 0;
if (exp_nl) {
continue;
}
}
/* eoln */
if (v == B64_EOLN) {
ln = 0;
if (exp_nl) {
exp_nl = 0;
continue;
}
}
exp_nl = 0;
/* If we are at the end of input and it looks like a
* line, process it. */
if ((i + 1) == in_len && (((n & 3) == 0) || eof)) {
v = B64_EOF;
/* In case things were given us in really small
records (so two '=' were given in separate
updates), eof may contain the incorrect number
of ending bytes to skip, so let's redo the count */
eof = 0;
if (d[n - 1] == '=') {
eof++;
}
if (d[n - 2] == '=') {
eof++;
}
/* There will never be more than two '=' */
}
if ((v == B64_EOF && (n & 3) == 0) || n >= 64) {
/* This is needed to work correctly on 64 byte input
* lines. We process the line and then need to
* accept the '\n' */
if (v != B64_EOF && n >= 64) {
exp_nl = 1;
}
if (n > 0) {
/* TODO(davidben): Switch this to EVP_DecodeBase64. */
v = EVP_DecodeBlock(out, d, n);
n = 0;
if (v < 0) {
rv = 0;
goto end;
}
if (eof > v) {
rv = -1;
goto end;
}
ret += (v - eof);
} else {
eof = 1;
v = 0;
}
/* This is the case where we have had a short
* but valid input line */
if (v < (int)ctx->length && eof) {
rv = 0;
goto end;
} else {
ctx->length = v;
}
if (seof >= 0) {
rv = 0;
goto end;
}
out += v;
}
}
rv = 1;
end:
*out_len = ret;
ctx->num = n;
ctx->line_num = ln;
ctx->expect_nl = exp_nl;
return rv;
}
int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *outl) {
int i;
*outl = 0;
if (ctx->num != 0) {
/* TODO(davidben): Switch this to EVP_DecodeBase64. */
i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num);
if (i < 0) {
return -1;
}
ctx->num = 0;
*outl = i;
return 1;
} else {
return 1;
}
}
int EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
size_t dst_len;
/* Trim spaces and tabs from the beginning of the input. */
while (src_len > 0) {
if (src[0] != ' ' && src[0] != '\t') {
break;
}
/* trim white space from the start of the line. */
while (conv_ascii2bin(*src) == B64_WS && src_len > 0) {
src++;
src_len--;
}
/* strip off stuff at the end of the line
* ascii2bin values B64_WS, B64_EOLN, B64_EOLN and B64_EOF */
while (src_len > 3 && B64_NOT_BASE64(conv_ascii2bin(src[src_len - 1]))) {
src_len--;
/* Trim newlines, spaces and tabs from the end of the line. */
while (src_len > 0) {
switch (src[src_len-1]) {
case ' ':
case '\t':
case '\r':
case '\n':
src_len--;
continue;
}
break;
}
if (!EVP_DecodedLength(&dst_len, src_len) || dst_len > INT_MAX) {
return -1;
}
if (!EVP_DecodeBase64(dst, &dst_len, dst_len, src, src_len)) {
size_t dst_len;
if (!EVP_DecodedLength(&dst_len, src_len) ||
dst_len > INT_MAX ||
!EVP_DecodeBase64(dst, &dst_len, dst_len, src, src_len)) {
return -1;
}
@@ -458,21 +436,3 @@ int EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) {
return dst_len;
}
int EVP_EncodedLength(size_t *out_len, size_t len) {
if (len + 2 < len) {
return 0;
}
len += 2;
len /= 3;
if (((len << 2) >> 2) != len) {
return 0;
}
len <<= 2;
if (len + 1 < len) {
return 0;
}
len++;
*out_len = len;
return 1;
}
+311 -45
View File
@@ -15,76 +15,203 @@
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#include <openssl/base64.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
enum encoding_relation {
// canonical indicates that the encoding is the expected encoding of the
// input.
canonical,
// valid indicates that the encoding is /a/ valid encoding of the input, but
// need not be the canonical one.
valid,
// invalid indicates that the encoded data is valid.
invalid,
};
struct TestVector {
enum encoding_relation relation;
const char *decoded;
const char *encoded;
};
// Test vectors from RFC 4648.
static const TestVector kTestVectors[] = {
{ "", "" },
{ "f" , "Zg==" },
{ "fo", "Zm8=" },
{ "foo", "Zm9v" },
{ "foob", "Zm9vYg==" },
{ "fooba", "Zm9vYmE=" },
{ "foobar", "Zm9vYmFy" },
{canonical, "", ""},
{canonical, "f", "Zg==\n"},
{canonical, "fo", "Zm8=\n"},
{canonical, "foo", "Zm9v\n"},
{canonical, "foob", "Zm9vYg==\n"},
{canonical, "fooba", "Zm9vYmE=\n"},
{canonical, "foobar", "Zm9vYmFy\n"},
{valid, "foobar", "Zm9vYmFy\n\n"},
{valid, "foobar", " Zm9vYmFy\n\n"},
{valid, "foobar", " Z m 9 v Y m F y\n\n"},
{invalid, "", "Zm9vYmFy=\n"},
{invalid, "", "Zm9vYmFy==\n"},
{invalid, "", "Zm9vYmFy===\n"},
{invalid, "", "Z"},
{invalid, "", "Z\n"},
{invalid, "", "ab!c"},
{invalid, "", "ab=c"},
{invalid, "", "abc"},
{canonical, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eA==\n"},
{valid, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eA\n==\n"},
{valid, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eA=\n=\n"},
{invalid, "",
"eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eA=\n==\n"},
{canonical, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4\neHh4eHh"
"4eHh4eHh4\n"},
{canonical,
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4\neHh4eHh"
"4eHh4eHh4eHh4eA==\n"},
{valid, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh\n4eHh4eHh"
"4eHh4eHh4eHh4eA==\n"},
{valid, "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4e"
"Hh4eHh4eHh4eA==\n"},
{invalid, "",
"eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eA=="
"\neHh4eHh4eHh4eHh4eHh4eHh4\n"},
// A '-' has traditionally been treated as the end of the data by OpenSSL
// and anything following would be ignored. BoringSSL does not accept this
// non-standard extension.
{invalid, "", "Zm9vYmFy-anythinggoes"},
{invalid, "", "Zm9vYmFy\n-anythinggoes"},
// CVE-2015-0292
{invalid, "",
"ZW5jb2RlIG1lCg==========================================================="
"=======\n"},
};
static const size_t kNumTests = sizeof(kTestVectors) / sizeof(kTestVectors[0]);
static bool TestEncode() {
for (size_t i = 0; i < kNumTests; i++) {
// RemoveNewlines returns a copy of |in| with all '\n' characters removed.
static std::string RemoveNewlines(const char *in) {
std::string ret;
const size_t in_len = strlen(in);
size_t i;
for (i = 0; i < in_len; i++) {
if (in[i] != '\n') {
ret.push_back(in[i]);
}
}
return ret;
}
static bool TestEncodeBlock() {
for (unsigned i = 0; i < kNumTests; i++) {
const TestVector *t = &kTestVectors[i];
uint8_t out[9];
size_t len = EVP_EncodeBlock(out, (const uint8_t*)t->decoded,
strlen(t->decoded));
if (len != strlen(t->encoded) ||
memcmp(out, t->encoded, len) != 0) {
if (t->relation != canonical) {
continue;
}
const size_t decoded_len = strlen(t->decoded);
size_t max_encoded_len;
if (!EVP_EncodedLength(&max_encoded_len, decoded_len)) {
fprintf(stderr, "#%u: EVP_EncodedLength failed\n", i);
return false;
}
std::vector<uint8_t> out_vec(max_encoded_len);
uint8_t *out = out_vec.data();
size_t len = EVP_EncodeBlock(out, (const uint8_t *)t->decoded, decoded_len);
std::string encoded(RemoveNewlines(t->encoded));
if (len != encoded.size() ||
memcmp(out, encoded.data(), len) != 0) {
fprintf(stderr, "encode(\"%s\") = \"%.*s\", want \"%s\"\n",
t->decoded, (int)len, (const char*)out, t->encoded);
t->decoded, (int)len, (const char*)out, encoded.c_str());
return false;
}
}
return true;
}
static bool TestDecode() {
uint8_t out[6];
static bool TestDecodeBase64() {
size_t len;
for (size_t i = 0; i < kNumTests; i++) {
// Test the normal API.
for (unsigned i = 0; i < kNumTests; i++) {
const TestVector *t = &kTestVectors[i];
size_t expected_len = strlen(t->decoded);
if (!EVP_DecodeBase64(out, &len, sizeof(out),
(const uint8_t*)t->encoded, strlen(t->encoded))) {
fprintf(stderr, "decode(\"%s\") failed\n", t->encoded);
return false;
}
if (len != strlen(t->decoded) ||
memcmp(out, t->decoded, len) != 0) {
fprintf(stderr, "decode(\"%s\") = \"%.*s\", want \"%s\"\n",
t->encoded, (int)len, (const char*)out, t->decoded);
return false;
if (t->relation == valid) {
// The non-canonical encodings will generally have odd whitespace etc
// that |EVP_DecodeBase64| will reject.
continue;
}
const std::string encoded(RemoveNewlines(t->encoded));
std::vector<uint8_t> out_vec(encoded.size());
uint8_t *out = out_vec.data();
int ok = EVP_DecodeBase64(out, &len, out_vec.size(),
(const uint8_t *)encoded.data(), encoded.size());
if (t->relation == invalid) {
if (ok) {
fprintf(stderr, "decode(\"%s\") didn't fail but should have\n",
encoded.c_str());
return false;
}
} else if (t->relation == canonical) {
if (!ok) {
fprintf(stderr, "decode(\"%s\") failed\n", encoded.c_str());
return false;
}
if (len != strlen(t->decoded) ||
memcmp(out, t->decoded, len) != 0) {
fprintf(stderr, "decode(\"%s\") = \"%.*s\", want \"%s\"\n",
encoded.c_str(), (int)len, (const char*)out, t->decoded);
return false;
}
}
}
return true;
}
static bool TestDecodeBlock() {
for (unsigned i = 0; i < kNumTests; i++) {
const TestVector *t = &kTestVectors[i];
if (t->relation != canonical) {
continue;
}
std::string encoded(RemoveNewlines(t->encoded));
std::vector<uint8_t> out_vec(encoded.size());
uint8_t *out = out_vec.data();
// Test that the padding behavior of the deprecated API is preserved.
int ret = EVP_DecodeBlock(out, (const uint8_t*)t->encoded,
strlen(t->encoded));
int ret =
EVP_DecodeBlock(out, (const uint8_t *)encoded.data(), encoded.size());
if (ret < 0) {
fprintf(stderr, "decode(\"%s\") failed\n", t->encoded);
fprintf(stderr, "EVP_DecodeBlock(\"%s\") failed\n", t->encoded);
return false;
}
if (ret % 3 != 0) {
fprintf(stderr, "EVP_DecodeBlock did not ignore padding\n");
return false;
}
size_t expected_len = strlen(t->decoded);
if (expected_len % 3 != 0) {
ret -= 3 - (expected_len % 3);
}
@@ -96,19 +223,155 @@ static bool TestDecode() {
}
}
if (EVP_DecodeBase64(out, &len, sizeof(out), (const uint8_t*)"a!bc", 4)) {
fprintf(stderr, "Failed to reject invalid characters in the middle.\n");
return false;
return true;
}
static bool TestEncodeDecode() {
for (unsigned test_num = 0; test_num < kNumTests; test_num++) {
const TestVector *t = &kTestVectors[test_num];
EVP_ENCODE_CTX ctx;
const size_t decoded_len = strlen(t->decoded);
if (t->relation == canonical) {
size_t max_encoded_len;
if (!EVP_EncodedLength(&max_encoded_len, decoded_len)) {
fprintf(stderr, "#%u: EVP_EncodedLength failed\n", test_num);
return false;
}
// EVP_EncodeUpdate will output new lines every 64 bytes of output so we
// need slightly more than |EVP_EncodedLength| returns. */
max_encoded_len += (max_encoded_len + 63) >> 6;
std::vector<uint8_t> out_vec(max_encoded_len);
uint8_t *out = out_vec.data();
EVP_EncodeInit(&ctx);
int out_len;
EVP_EncodeUpdate(&ctx, out, &out_len,
reinterpret_cast<const uint8_t *>(t->decoded),
decoded_len);
size_t total = out_len;
EVP_EncodeFinal(&ctx, out + total, &out_len);
total += out_len;
if (total != strlen(t->encoded) || memcmp(out, t->encoded, total) != 0) {
fprintf(stderr, "#%u: EVP_EncodeUpdate produced different output: '%s' (%u)\n",
test_num, out, static_cast<unsigned>(total));
return false;
}
}
std::vector<uint8_t> out_vec(strlen(t->encoded));
uint8_t *out = out_vec.data();
EVP_DecodeInit(&ctx);
int out_len;
size_t total = 0;
int ret = EVP_DecodeUpdate(&ctx, out, &out_len,
reinterpret_cast<const uint8_t *>(t->encoded),
strlen(t->encoded));
if (ret != -1) {
total = out_len;
ret = EVP_DecodeFinal(&ctx, out + total, &out_len);
total += out_len;
}
switch (t->relation) {
case canonical:
case valid:
if (ret == -1) {
fprintf(stderr, "#%u: EVP_DecodeUpdate failed\n", test_num);
return false;
}
if (total != decoded_len || memcmp(out, t->decoded, decoded_len)) {
fprintf(stderr, "#%u: EVP_DecodeUpdate produced incorrect output\n",
test_num);
return false;
}
break;
case invalid:
if (ret != -1) {
fprintf(stderr, "#%u: EVP_DecodeUpdate was successful but shouldn't have been\n", test_num);
return false;
}
break;
}
}
if (EVP_DecodeBase64(out, &len, sizeof(out), (const uint8_t*)"a=bc", 4)) {
fprintf(stderr, "Failed to reject invalid characters in the middle.\n");
return false;
}
return true;
}
if (EVP_DecodeBase64(out, &len, sizeof(out), (const uint8_t*)"abc", 4)) {
fprintf(stderr, "Failed to reject invalid input length.\n");
return false;
static bool TestDecodeUpdateStreaming() {
for (unsigned test_num = 0; test_num < kNumTests; test_num++) {
const TestVector *t = &kTestVectors[test_num];
if (t->relation == invalid) {
continue;
}
const size_t encoded_len = strlen(t->encoded);
std::vector<uint8_t> out(encoded_len);
for (size_t chunk_size = 1; chunk_size <= encoded_len; chunk_size++) {
size_t out_len = 0;
EVP_ENCODE_CTX ctx;
EVP_DecodeInit(&ctx);
for (size_t i = 0; i < encoded_len;) {
size_t todo = encoded_len - i;
if (todo > chunk_size) {
todo = chunk_size;
}
int bytes_written;
int ret = EVP_DecodeUpdate(
&ctx, out.data() + out_len, &bytes_written,
reinterpret_cast<const uint8_t *>(t->encoded + i), todo);
i += todo;
switch (ret) {
case -1:
fprintf(stderr, "#%u: EVP_DecodeUpdate returned error\n", test_num);
return 0;
case 0:
out_len += bytes_written;
if (i == encoded_len ||
(i + 1 == encoded_len && t->encoded[i] == '\n') ||
/* If there was an '-' in the input (which means “EOF”) then
* this loop will continue to test that |EVP_DecodeUpdate| will
* ignore the remainder of the input. */
strchr(t->encoded, '-') != nullptr) {
break;
}
fprintf(stderr,
"#%u: EVP_DecodeUpdate returned zero before end of "
"encoded data\n",
test_num);
return 0;
default:
out_len += bytes_written;
}
}
int bytes_written;
int ret = EVP_DecodeFinal(&ctx, out.data() + out_len, &bytes_written);
if (ret == -1) {
fprintf(stderr, "#%u: EVP_DecodeFinal returned error\n", test_num);
return 0;
}
out_len += bytes_written;
if (out_len != strlen(t->decoded) ||
memcmp(out.data(), t->decoded, out_len) != 0) {
fprintf(stderr, "#%u: incorrect output\n", test_num);
return 0;
}
}
}
return true;
@@ -117,8 +380,11 @@ static bool TestDecode() {
int main(void) {
CRYPTO_library_init();
if (!TestEncode() ||
!TestDecode()) {
if (!TestEncodeBlock() ||
!TestDecodeBase64() ||
!TestDecodeBlock() ||
!TestDecodeUpdateStreaming() ||
!TestEncodeDecode()) {
return 1;
}
+2 -2
View File
@@ -27,10 +27,10 @@
#include <unistd.h>
#else
#include <io.h>
#pragma warning(push, 3)
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma warning(pop)
OPENSSL_MSVC_PRAGMA(warning(pop))
#endif
#include <openssl/bio.h>
+8 -2
View File
@@ -66,10 +66,10 @@
#include <arpa/inet.h>
#include <unistd.h>
#else
#pragma warning(push, 3)
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma warning(pop)
OPENSSL_MSVC_PRAGMA(warning(pop))
#endif
#include <openssl/buf.h>
@@ -538,6 +538,12 @@ int BIO_set_conn_port(BIO *bio, const char *port_str) {
return BIO_ctrl(bio, BIO_C_SET_CONNECT, 1, (void*) port_str);
}
int BIO_set_conn_int_port(BIO *bio, const int *port) {
char buf[DECIMAL_SIZE(int) + 1];
BIO_snprintf(buf, sizeof(buf), "%d", *port);
return BIO_set_conn_port(bio, buf);
}
int BIO_set_nbio(BIO *bio, int on) {
return BIO_ctrl(bio, BIO_C_SET_NBIO, on, NULL);
}
+20 -15
View File
@@ -63,9 +63,9 @@
#include <unistd.h>
#else
#include <io.h>
#pragma warning(push, 3)
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <windows.h>
#pragma warning(pop)
OPENSSL_MSVC_PRAGMA(warning(pop))
#endif
#include <openssl/buf.h>
@@ -108,20 +108,25 @@ static int bio_fd_non_fatal_error(int err) {
}
#if defined(OPENSSL_WINDOWS)
int bio_fd_should_retry(int i) {
if (i == -1) {
return bio_fd_non_fatal_error((int)GetLastError());
}
return 0;
}
#define BORINGSSL_ERRNO (int)GetLastError()
#define BORINGSSL_CLOSE _close
#define BORINGSSL_LSEEK _lseek
#define BORINGSSL_READ _read
#define BORINGSSL_WRITE _write
#else
#define BORINGSSL_ERRNO errno
#define BORINGSSL_CLOSE close
#define BORINGSSL_LSEEK lseek
#define BORINGSSL_READ read
#define BORINGSSL_WRITE write
#endif
int bio_fd_should_retry(int i) {
if (i == -1) {
return bio_fd_non_fatal_error(errno);
return bio_fd_non_fatal_error(BORINGSSL_ERRNO);
}
return 0;
}
#endif
BIO *BIO_new_fd(int fd, int close_flag) {
BIO *ret = BIO_new(BIO_s_fd());
@@ -145,7 +150,7 @@ static int fd_free(BIO *bio) {
if (bio->shutdown) {
if (bio->init) {
close(bio->num);
BORINGSSL_CLOSE(bio->num);
}
bio->init = 0;
}
@@ -155,7 +160,7 @@ static int fd_free(BIO *bio) {
static int fd_read(BIO *b, char *out, int outl) {
int ret = 0;
ret = read(b->num, out, outl);
ret = BORINGSSL_READ(b->num, out, outl);
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (bio_fd_should_retry(ret)) {
@@ -167,7 +172,7 @@ static int fd_read(BIO *b, char *out, int outl) {
}
static int fd_write(BIO *b, const char *in, int inl) {
int ret = write(b->num, in, inl);
int ret = BORINGSSL_WRITE(b->num, in, inl);
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (bio_fd_should_retry(ret)) {
@@ -188,14 +193,14 @@ static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) {
case BIO_C_FILE_SEEK:
ret = 0;
if (b->init) {
ret = (long)lseek(b->num, num, SEEK_SET);
ret = (long)BORINGSSL_LSEEK(b->num, num, SEEK_SET);
}
break;
case BIO_C_FILE_TELL:
case BIO_CTRL_INFO:
ret = 0;
if (b->init) {
ret = (long)lseek(b->num, 0, SEEK_CUR);
ret = (long)BORINGSSL_LSEEK(b->num, 0, SEEK_CUR);
}
break;
case BIO_C_SET_FD:
+2 -2
View File
@@ -67,9 +67,9 @@ typedef unsigned short u_short;
#include <sys/types.h>
#include <sys/socket.h>
#else
#pragma warning(push, 3)
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <winsock2.h>
#pragma warning(pop)
OPENSSL_MSVC_PRAGMA(warning(pop))
typedef int socklen_t;
#endif
+10 -2
View File
@@ -63,9 +63,9 @@
#if !defined(OPENSSL_WINDOWS)
#include <unistd.h>
#else
#pragma warning(push, 3)
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <winsock2.h>
#pragma warning(pop)
OPENSSL_MSVC_PRAGMA(warning(pop))
#pragma comment(lib, "Ws2_32.lib")
#endif
@@ -110,7 +110,11 @@ static int sock_read(BIO *b, char *out, int outl) {
}
bio_clear_socket_error();
#if defined(OPENSSL_WINDOWS)
ret = recv(b->num, out, outl, 0);
#else
ret = read(b->num, out, outl);
#endif
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (bio_fd_should_retry(ret)) {
@@ -124,7 +128,11 @@ static int sock_write(BIO *b, const char *in, int inl) {
int ret;
bio_clear_socket_error();
#if defined(OPENSSL_WINDOWS)
ret = send(b->num, in, inl, 0);
#else
ret = write(b->num, in, inl);
#endif
BIO_clear_retry_flags(b);
if (ret <= 0) {
if (bio_fd_should_retry(ret)) {
+2 -2
View File
@@ -26,10 +26,10 @@
#include <netdb.h>
#include <unistd.h>
#else
#pragma warning(push, 3)
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma warning(pop)
OPENSSL_MSVC_PRAGMA(warning(pop))
#endif
#include "internal.h"
+6
View File
@@ -850,11 +850,17 @@ static bool test_div_word(FILE *fp) {
return false;
}
BN_ULONG s = b->d[0];
BN_ULONG rmod = BN_mod_word(b.get(), s);
BN_ULONG r = BN_div_word(b.get(), s);
if (r == (BN_ULONG)-1) {
return false;
}
if (rmod != r) {
fprintf(stderr, "Mod (word) test failed!\n");
return false;
}
if (fp != NULL) {
BN_print_fp(fp, a.get());
puts_fp(fp, " / ");
+14
View File
@@ -56,6 +56,8 @@
#include <openssl/bn.h>
#include <openssl/mem.h>
#include "internal.h"
@@ -198,3 +200,15 @@ int BN_is_word(const BIGNUM *bn, BN_ULONG w) {
int BN_is_odd(const BIGNUM *bn) {
return bn->top > 0 && (bn->d[0] & 1) == 1;
}
int BN_equal_consttime(const BIGNUM *a, const BIGNUM *b) {
if (a->top != b->top) {
return 0;
}
int limbs_are_equal =
CRYPTO_memcmp(a->d, b->d, (size_t)a->top * sizeof(a->d[0])) == 0;
return constant_time_select_int(constant_time_eq_int(a->neg, b->neg),
limbs_are_equal, 0);
}
+9 -4
View File
@@ -577,12 +577,14 @@ BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out) {
return NULL;
}
int out_is_alloced = 0;
if (out == NULL) {
out = BN_new();
}
if (out == NULL) {
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
return NULL;
if (out == NULL) {
OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
return NULL;
}
out_is_alloced = 1;
}
if (in_len == 0) {
@@ -592,6 +594,9 @@ BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out) {
in += 4;
if (BN_bin2bn(in, in_len, out) == NULL) {
if (out_is_alloced) {
BN_free(out);
}
return NULL;
}
out->neg = ((*in) & 0x80) != 0;
+14
View File
@@ -644,6 +644,20 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) {
return (BN_ULONG) -1;
}
#ifndef BN_ULLONG
/* If |w| is too long and we don't have |BN_ULLONG| then we need to fall back
* to using |BN_div_word|. */
if (w > ((BN_ULONG)1 << BN_BITS4)) {
BIGNUM *tmp = BN_dup(a);
if (tmp == NULL) {
return (BN_ULONG)-1;
}
ret = BN_div_word(tmp, w);
BN_free(tmp);
return ret;
}
#endif
w &= BN_MASK2;
for (i = a->top - 1; i >= 0; i--) {
#ifndef BN_ULLONG
+21 -345
View File
@@ -576,41 +576,7 @@ err:
int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m,
BN_CTX *ctx) {
/* For even modulus m = 2^k*m_odd, it might make sense to compute
* a^p mod m_odd and a^p mod 2^k separately (with Montgomery
* exponentiation for the odd part), using appropriate exponent
* reductions, and combine the results using the CRT.
*
* For now, we use Montgomery only if the modulus is odd; otherwise,
* exponentiation using the reciprocal-based quick remaindering
* algorithm is used.
*
* (Timing obtained with expspeed.c [computations a^p mod m
* where a, p, m are of the same length: 256, 512, 1024, 2048,
* 4096, 8192 bits], compared to the running time of the
* standard algorithm:
*
* BN_mod_exp_mont 33 .. 40 % [AMD K6-2, Linux, debug configuration]
* 55 .. 77 % [UltraSparc processor, but
* debug-solaris-sparcv8-gcc conf.]
*
* BN_mod_exp_recp 50 .. 70 % [AMD K6-2, Linux, debug configuration]
* 62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc]
*
* On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont
* at 2048 and more bits, but at 512 and 1024 bits, it was
* slower even than the standard algorithm!
*
* "Real" timings [linux-elf, solaris-sparcv9-gcc configurations]
* should be obtained when the new Montgomery reduction code
* has been integrated into OpenSSL.) */
if (BN_is_odd(m)) {
if (a->top == 1 && !a->neg && BN_get_flags(p, BN_FLG_CONSTTIME) == 0) {
BN_ULONG A = a->d[0];
return BN_mod_exp_mont_word(r, A, p, m, ctx, NULL);
}
return BN_mod_exp_mont(r, a, p, m, ctx, NULL);
}
@@ -1234,151 +1200,21 @@ err:
int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
const BIGNUM *m, BN_CTX *ctx,
const BN_MONT_CTX *mont) {
BN_MONT_CTX *new_mont = NULL;
int b, bits, ret = 0;
int r_is_one;
BN_ULONG w, next_w;
BIGNUM *d, *r, *t;
BIGNUM *swap_tmp;
#define BN_MOD_MUL_WORD(r, w, m) \
(BN_mul_word(r, (w)) && \
(/* BN_ucmp(r, (m)) < 0 ? 1 :*/ \
(BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1))))
/* BN_MOD_MUL_WORD is only used with 'w' large, so the BN_ucmp test is
* probably more overhead than always using BN_mod (which uses BN_copy if a
* similar test returns true). We can use BN_mod and do not need BN_nnmod
* because our accumulator is never negative (the result of BN_mod does not
* depend on the sign of the modulus). */
#define BN_TO_MONTGOMERY_WORD(r, w, mont) \
(BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx))
BIGNUM a_bignum;
BN_init(&a_bignum);
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
int ret = 0;
if (!BN_is_odd(m)) {
OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
if (m->top == 1) {
a %= m->d[0]; /* make sure that 'a' is reduced */
}
bits = BN_num_bits(p);
if (bits == 0) {
/* x**0 mod 1 is still zero. */
if (BN_is_one(m)) {
BN_zero(rr);
return 1;
}
return BN_one(rr);
}
if (a == 0) {
BN_zero(rr);
return 1;
}
BN_CTX_start(ctx);
d = BN_CTX_get(ctx);
r = BN_CTX_get(ctx);
t = BN_CTX_get(ctx);
if (d == NULL || r == NULL || t == NULL) {
if (!BN_set_word(&a_bignum, a)) {
OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR);
goto err;
}
/* Allocate a montgomery context if it was not supplied by the caller. */
if (mont == NULL) {
new_mont = BN_MONT_CTX_new();
if (new_mont == NULL || !BN_MONT_CTX_set(new_mont, m, ctx)) {
goto err;
}
mont = new_mont;
}
r_is_one = 1; /* except for Montgomery factor */
/* bits-1 >= 0 */
/* The result is accumulated in the product r*w. */
w = a; /* bit 'bits-1' of 'p' is always set */
for (b = bits - 2; b >= 0; b--) {
/* First, square r*w. */
next_w = w * w;
if ((next_w / w) != w) {
/* overflow */
if (r_is_one) {
if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) {
goto err;
}
r_is_one = 0;
} else {
if (!BN_MOD_MUL_WORD(r, w, m)) {
goto err;
}
}
next_w = 1;
}
w = next_w;
if (!r_is_one) {
if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) {
goto err;
}
}
/* Second, multiply r*w by 'a' if exponent bit is set. */
if (BN_is_bit_set(p, b)) {
next_w = w * a;
if ((next_w / a) != w) {
/* overflow */
if (r_is_one) {
if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) {
goto err;
}
r_is_one = 0;
} else {
if (!BN_MOD_MUL_WORD(r, w, m)) {
goto err;
}
}
next_w = a;
}
w = next_w;
}
}
/* Finally, set r:=r*w. */
if (w != 1) {
if (r_is_one) {
if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) {
goto err;
}
r_is_one = 0;
} else {
if (!BN_MOD_MUL_WORD(r, w, m)) {
goto err;
}
}
}
if (r_is_one) {
/* can happen only if a == 1*/
if (!BN_one(rr)) {
goto err;
}
} else {
if (!BN_from_montgomery(rr, r, mont, ctx)) {
goto err;
}
}
ret = 1;
ret = BN_mod_exp_mont(rr, &a_bignum, p, m, ctx, mont);
err:
BN_MONT_CTX_free(new_mont);
BN_CTX_end(ctx);
BN_free(&a_bignum);
return ret;
}
@@ -1387,37 +1223,12 @@ err:
int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m,
BN_CTX *ctx, const BN_MONT_CTX *mont) {
int i, j, bits, b, bits1, bits2, ret = 0, wpos1, wpos2, window1, window2,
wvalue1, wvalue2;
int r_is_one = 1;
BIGNUM *d, *r;
const BIGNUM *a_mod_m;
/* Tables of variables obtained from 'ctx' */
BIGNUM *val1[TABLE_SIZE], *val2[TABLE_SIZE];
BIGNUM tmp;
BN_init(&tmp);
int ret = 0;
BN_MONT_CTX *new_mont = NULL;
if (!(m->d[0] & 1)) {
OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
bits1 = BN_num_bits(p1);
bits2 = BN_num_bits(p2);
if (bits1 == 0 && bits2 == 0) {
ret = BN_one(rr);
return ret;
}
bits = (bits1 > bits2) ? bits1 : bits2;
BN_CTX_start(ctx);
d = BN_CTX_get(ctx);
r = BN_CTX_get(ctx);
val1[0] = BN_CTX_get(ctx);
val2[0] = BN_CTX_get(ctx);
if (!d || !r || !val1[0] || !val2[0]) {
goto err;
}
/* Allocate a montgomery context if it was not supplied by the caller. */
if (mont == NULL) {
new_mont = BN_MONT_CTX_new();
@@ -1427,156 +1238,21 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
mont = new_mont;
}
window1 = BN_window_bits_for_exponent_size(bits1);
window2 = BN_window_bits_for_exponent_size(bits2);
/* Build table for a1: val1[i] := a1^(2*i + 1) mod m for i = 0 ..
* 2^(window1-1) */
if (a1->neg || BN_ucmp(a1, m) >= 0) {
if (!BN_mod(val1[0], a1, m, ctx)) {
goto err;
}
a_mod_m = val1[0];
} else {
a_mod_m = a1;
}
if (BN_is_zero(a_mod_m)) {
BN_zero(rr);
ret = 1;
/* BN_mod_mul_montgomery removes one Montgomery factor, so passing one
* Montgomery-encoded and one non-Montgomery-encoded value gives a
* non-Montgomery-encoded result. */
if (!BN_mod_exp_mont(rr, a1, p1, m, ctx, mont) ||
!BN_mod_exp_mont(&tmp, a2, p2, m, ctx, mont) ||
!BN_to_montgomery(rr, rr, mont, ctx) ||
!BN_mod_mul_montgomery(rr, rr, &tmp, mont, ctx)) {
goto err;
}
if (!BN_to_montgomery(val1[0], a_mod_m, mont, ctx)) {
goto err;
}
if (window1 > 1) {
if (!BN_mod_mul_montgomery(d, val1[0], val1[0], mont, ctx)) {
goto err;
}
j = 1 << (window1 - 1);
for (i = 1; i < j; i++) {
if (((val1[i] = BN_CTX_get(ctx)) == NULL) ||
!BN_mod_mul_montgomery(val1[i], val1[i - 1], d, mont, ctx)) {
goto err;
}
}
}
/* Build table for a2: val2[i] := a2^(2*i + 1) mod m for i = 0 ..
* 2^(window2-1) */
if (a2->neg || BN_ucmp(a2, m) >= 0) {
if (!BN_mod(val2[0], a2, m, ctx)) {
goto err;
}
a_mod_m = val2[0];
} else {
a_mod_m = a2;
}
if (BN_is_zero(a_mod_m)) {
BN_zero(rr);
ret = 1;
goto err;
}
if (!BN_to_montgomery(val2[0], a_mod_m, mont, ctx)) {
goto err;
}
if (window2 > 1) {
if (!BN_mod_mul_montgomery(d, val2[0], val2[0], mont, ctx)) {
goto err;
}
j = 1 << (window2 - 1);
for (i = 1; i < j; i++) {
if (((val2[i] = BN_CTX_get(ctx)) == NULL) ||
!BN_mod_mul_montgomery(val2[i], val2[i - 1], d, mont, ctx)) {
goto err;
}
}
}
/* Now compute the power product, using independent windows. */
r_is_one = 1;
wvalue1 = 0; /* The 'value' of the first window */
wvalue2 = 0; /* The 'value' of the second window */
wpos1 = 0; /* If wvalue1 > 0, the bottom bit of the first window */
wpos2 = 0; /* If wvalue2 > 0, the bottom bit of the second window */
if (!BN_to_montgomery(r, BN_value_one(), mont, ctx)) {
goto err;
}
for (b = bits - 1; b >= 0; b--) {
if (!r_is_one) {
if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) {
goto err;
}
}
if (!wvalue1 && BN_is_bit_set(p1, b)) {
/* consider bits b-window1+1 .. b for this window */
i = b - window1 + 1;
/* works for i<0 */
while (!BN_is_bit_set(p1, i)) {
i++;
}
wpos1 = i;
wvalue1 = 1;
for (i = b - 1; i >= wpos1; i--) {
wvalue1 <<= 1;
if (BN_is_bit_set(p1, i)) {
wvalue1++;
}
}
}
if (!wvalue2 && BN_is_bit_set(p2, b)) {
/* consider bits b-window2+1 .. b for this window */
i = b - window2 + 1;
while (!BN_is_bit_set(p2, i)) {
i++;
}
wpos2 = i;
wvalue2 = 1;
for (i = b - 1; i >= wpos2; i--) {
wvalue2 <<= 1;
if (BN_is_bit_set(p2, i)) {
wvalue2++;
}
}
}
if (wvalue1 && b == wpos1) {
/* wvalue1 is odd and < 2^window1 */
if (!BN_mod_mul_montgomery(r, r, val1[wvalue1 >> 1], mont, ctx)) {
goto err;
}
wvalue1 = 0;
r_is_one = 0;
}
if (wvalue2 && b == wpos2) {
/* wvalue2 is odd and < 2^window2 */
if (!BN_mod_mul_montgomery(r, r, val2[wvalue2 >> 1], mont, ctx)) {
goto err;
}
wvalue2 = 0;
r_is_one = 0;
}
}
if (!BN_from_montgomery(rr, r, mont, ctx)) {
goto err;
}
ret = 1;
err:
BN_MONT_CTX_free(new_mont);
BN_CTX_end(ctx);
BN_free(&tmp);
return ret;
}
+14 -13
View File
@@ -668,6 +668,12 @@ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, int *out_no_inverse,
sign = -sign;
}
if (!BN_is_one(A)) {
*out_no_inverse = 1;
OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
goto err;
}
/*
* The while loop (Euclid's algorithm) ends when
* A == gcd(a,n);
@@ -683,22 +689,17 @@ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, int *out_no_inverse,
}
/* Now Y*a == A (mod |n|). */
if (BN_is_one(A)) {
/* Y*a == 1 (mod |n|) */
if (!Y->neg && BN_ucmp(Y, n) < 0) {
if (!BN_copy(R, Y)) {
goto err;
}
} else {
if (!BN_nnmod(R, Y, n, ctx)) {
goto err;
}
/* Y*a == 1 (mod |n|) */
if (!Y->neg && BN_ucmp(Y, n) < 0) {
if (!BN_copy(R, Y)) {
goto err;
}
} else {
*out_no_inverse = 1;
OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
goto err;
if (!BN_nnmod(R, Y, n, ctx)) {
goto err;
}
}
ret = R;
err:
+2 -2
View File
@@ -126,9 +126,9 @@
#include <openssl/base.h>
#if defined(OPENSSL_X86_64) && defined(_MSC_VER)
#pragma warning(push, 3)
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <intrin.h>
#pragma warning(pop)
OPENSSL_MSVC_PRAGMA(warning(pop))
#pragma intrinsic(__umulh, _umul128)
#endif
+6 -6
View File
@@ -289,14 +289,14 @@ err:
return ret;
}
BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock,
const BIGNUM *mod, BN_CTX *bn_ctx) {
int BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock,
const BIGNUM *mod, BN_CTX *bn_ctx) {
CRYPTO_MUTEX_lock_read(lock);
BN_MONT_CTX *ctx = *pmont;
CRYPTO_MUTEX_unlock(lock);
CRYPTO_MUTEX_unlock_read(lock);
if (ctx) {
return ctx;
return 1;
}
CRYPTO_MUTEX_lock_write(lock);
@@ -317,8 +317,8 @@ BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock,
*pmont = ctx;
out:
CRYPTO_MUTEX_unlock(lock);
return ctx;
CRYPTO_MUTEX_unlock_write(lock);
return ctx != NULL;
}
int BN_to_montgomery(BIGNUM *ret, const BIGNUM *a, const BN_MONT_CTX *mont,
+25 -21
View File
@@ -88,34 +88,26 @@ void BUF_MEM_free(BUF_MEM *buf) {
OPENSSL_free(buf);
}
static size_t buf_mem_grow(BUF_MEM *buf, size_t len, char clean) {
char *new_buf;
size_t n, alloc_size;
if (buf->length >= len) {
buf->length = len;
return len;
}
if (buf->max >= len) {
memset(&buf->data[buf->length], 0, len - buf->length);
buf->length = len;
return len;
static int buf_mem_reserve(BUF_MEM *buf, size_t cap, int clean) {
if (buf->max >= cap) {
return 1;
}
n = len + 3;
if (n < len) {
size_t n = cap + 3;
if (n < cap) {
/* overflow */
OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
return 0;
}
n = n / 3;
alloc_size = n * 4;
size_t alloc_size = n * 4;
if (alloc_size / 4 != n) {
/* overflow */
OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
return 0;
}
char *new_buf;
if (buf->data == NULL) {
new_buf = OPENSSL_malloc(alloc_size);
} else {
@@ -128,14 +120,26 @@ static size_t buf_mem_grow(BUF_MEM *buf, size_t len, char clean) {
if (new_buf == NULL) {
OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
len = 0;
} else {
buf->data = new_buf;
buf->max = alloc_size;
memset(&buf->data[buf->length], 0, len - buf->length);
buf->length = len;
return 0;
}
buf->data = new_buf;
buf->max = alloc_size;
return 1;
}
int BUF_MEM_reserve(BUF_MEM *buf, size_t cap) {
return buf_mem_reserve(buf, cap, 0 /* don't clear old buffer contents. */);
}
static size_t buf_mem_grow(BUF_MEM *buf, size_t len, int clean) {
if (!buf_mem_reserve(buf, len, clean)) {
return 0;
}
if (buf->length < len) {
memset(&buf->data[buf->length], 0, len - buf->length);
}
buf->length = len;
return len;
}
+5 -2
View File
@@ -43,7 +43,7 @@ static bool TestSkip() {
}
static bool TestGetUint() {
static const uint8_t kData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
static const uint8_t kData[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
uint8_t u8;
uint16_t u16;
uint32_t u32;
@@ -58,7 +58,10 @@ static bool TestGetUint() {
u32 == 0x40506 &&
CBS_get_u32(&data, &u32) &&
u32 == 0x708090a &&
!CBS_get_u8(&data, &u8);
CBS_get_last_u8(&data, &u8) &&
u8 == 0xb &&
!CBS_get_u8(&data, &u8) &&
!CBS_get_last_u8(&data, &u8);
}
static bool TestGetPrefixed() {
+27 -2
View File
@@ -128,6 +128,15 @@ int CBS_get_u32(CBS *cbs, uint32_t *out) {
return cbs_get_u(cbs, out, 4);
}
int CBS_get_last_u8(CBS *cbs, uint8_t *out) {
if (cbs->len == 0) {
return 0;
}
*out = cbs->data[cbs->len - 1];
cbs->len--;
return 1;
}
int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) {
const uint8_t *v;
if (!cbs_get(cbs, &v, len)) {
@@ -181,8 +190,14 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
return 0;
}
/* ITU-T X.690 section 8.1.2.3 specifies the format for identifiers with a tag
* number no greater than 30.
*
* If the number portion is 31 (0x1f, the largest value that fits in the
* allotted bits), then the tag is more than one byte long and the
* continuation bytes contain the tag number. This parser only supports tag
* numbers less than 31 (and thus single-byte tags). */
if ((tag & 0x1f) == 0x1f) {
/* Long form tags are not supported. */
return 0;
}
@@ -191,6 +206,8 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
}
size_t len;
/* The format for the length encoding is specified in ITU-T X.690 section
* 8.1.3. */
if ((length_byte & 0x80) == 0) {
/* Short form length. */
len = ((size_t) length_byte) + 2;
@@ -198,7 +215,9 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
*out_header_len = 2;
}
} else {
/* Long form length. */
/* The high bit indicate that this is the long form, while the next 7 bits
* encode the number of subsequent octets used to encode the length (ITU-T
* X.690 clause 8.1.3.5.b). */
const size_t num_bytes = length_byte & 0x7f;
uint32_t len32;
@@ -210,12 +229,18 @@ static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag,
return CBS_get_bytes(cbs, out, 2);
}
/* ITU-T X.690 clause 8.1.3.5.c specifies that the value 0xff shall not be
* used as the first byte of the length. If this parser encounters that
* value, num_bytes will be parsed as 127, which will fail the check below.
*/
if (num_bytes == 0 || num_bytes > 4) {
return 0;
}
if (!cbs_get_u(&header, &len32, num_bytes)) {
return 0;
}
/* ITU-T X.690 section 10.1 (DER length forms) requires encoding the length
* with the minimum number of octets. */
if (len32 < 128) {
/* Length should have used short-form encoding. */
return 0;
+1
View File
@@ -1124,3 +1124,4 @@ foreach (split("\n",$code)) {
print $_,"\n";
}
close STDOUT; # flush
+46 -62
View File
@@ -19,13 +19,13 @@
# P4 18.6/+84%
# Core2 9.56/+89% 4.83
# Westmere 9.50/+45% 3.35
# Sandy Bridge 10.7/+47% 3.24
# Haswell 8.22/+50% 2.89
# Silvermont 17.8/+36% 8.53
# Sandy Bridge 10.5/+47% 3.20
# Haswell 8.15/+50% 2.83
# Silvermont 17.4/+36% 8.35
# Sledgehammer 10.2/+54%
# Bulldozer 13.5/+50% 4.39(*)
# Bulldozer 13.4/+50% 4.38(*)
#
# (*) Bulldozer actually executes 4xXOP code path that delivers 3.50;
# (*) Bulldozer actually executes 4xXOP code path that delivers 3.55;
#
# Modified from upstream OpenSSL to remove the XOP code.
@@ -224,20 +224,18 @@ if ($xmm) {
&xor ($a, &DWP(4*0,$b)); # xor with input
&xor ($b_,&DWP(4*4,$b));
&mov (&DWP(4*0,"esp"),$a); # off-load for later write
&mov (&DWP(4*0,"esp"),$a);
&mov ($a,&wparam(0)); # load output pointer
&xor ($c, &DWP(4*8,$b));
&xor ($c_,&DWP(4*9,$b));
&xor ($d, &DWP(4*12,$b));
&xor ($d_,&DWP(4*14,$b));
&mov (&DWP(4*4,"esp"),$b_);
&mov ($b_,&DWP(4*0,"esp"));
&mov (&DWP(4*8,"esp"),$c);
&mov (&DWP(4*9,"esp"),$c_);
&mov (&DWP(4*12,"esp"),$d);
&mov (&DWP(4*14,"esp"),$d_);
&mov (&DWP(4*4,$a),$b_); # write output
&mov (&DWP(4*8,$a),$c);
&mov (&DWP(4*9,$a),$c_);
&mov (&DWP(4*12,$a),$d);
&mov (&DWP(4*14,$a),$d_);
&mov (&DWP(4*0,$a),$b_); # write output in order
&mov ($b_,&DWP(4*1,"esp"));
&mov ($c, &DWP(4*2,"esp"));
&mov ($c_,&DWP(4*3,"esp"));
@@ -254,45 +252,35 @@ if ($xmm) {
&xor ($d, &DWP(4*5,$b));
&xor ($d_,&DWP(4*6,$b));
&mov (&DWP(4*1,$a),$b_);
&mov ($b_,&DWP(4*4,"esp"));
&mov (&DWP(4*2,$a),$c);
&mov (&DWP(4*3,$a),$c_);
&mov (&DWP(4*4,$a),$b_);
&mov (&DWP(4*5,$a),$d);
&mov (&DWP(4*6,$a),$d_);
&mov ($c,&DWP(4*7,"esp"));
&mov ($d,&DWP(4*8,"esp"));
&mov ($d_,&DWP(4*9,"esp"));
&add ($c,&DWP(64+4*7,"esp"));
&mov ($b_, &DWP(4*10,"esp"));
&xor ($c,&DWP(4*7,$b));
&mov ($b_,&DWP(4*7,"esp"));
&mov ($c, &DWP(4*10,"esp"));
&mov ($c_,&DWP(4*11,"esp"));
&mov (&DWP(4*7,$a),$c);
&mov (&DWP(4*8,$a),$d);
&mov (&DWP(4*9,$a),$d_);
&add ($b_, &DWP(64+4*10,"esp"));
&add ($c_,&DWP(64+4*11,"esp"));
&xor ($b_, &DWP(4*10,$b));
&xor ($c_,&DWP(4*11,$b));
&mov (&DWP(4*10,$a),$b_);
&mov (&DWP(4*11,$a),$c_);
&mov ($c,&DWP(4*12,"esp"));
&mov ($c_,&DWP(4*14,"esp"));
&mov ($d, &DWP(4*13,"esp"));
&mov ($d_,&DWP(4*15,"esp"));
&add ($b_,&DWP(64+4*7,"esp"));
&add ($c, &DWP(64+4*10,"esp"));
&add ($c_,&DWP(64+4*11,"esp"));
&add ($d, &DWP(64+4*13,"esp"));
&add ($d_,&DWP(64+4*15,"esp"));
&xor ($b_,&DWP(4*7,$b));
&xor ($c, &DWP(4*10,$b));
&xor ($c_,&DWP(4*11,$b));
&xor ($d, &DWP(4*13,$b));
&xor ($d_,&DWP(4*15,$b));
&lea ($b,&DWP(4*16,$b));
&mov (&DWP(4*12,$a),$c);
&mov (&DWP(4*7,$a),$b_);
&mov ($b_,&DWP(4*0,"esp"));
&mov (&DWP(4*10,$a),$c);
&mov ($c,&wparam(2)); # len
&mov (&DWP(4*11,$a),$c_);
&mov (&DWP(4*13,$a),$d);
&mov (&DWP(4*14,$a),$c_);
&mov (&DWP(4*15,$a),$d_);
&mov (&DWP(4*0,$a),$b_);
&lea ($a,&DWP(4*16,$a));
&sub ($c,64);
&jnz (&label("outer_loop"));
@@ -567,12 +555,12 @@ my ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_-1)&3),($ai,$bi,$ci,$di)); # previous
my ($xa0,$xa1,$xa2,$xa3,$xt0,$xt1,$xt2,$xt3)=map("xmm$_",(0..7));
for($i=0;$i<256;$i+=64) {
#&movdqa ($xa0,&QWP($i+16*0-128,"ebx")); # it's there
&movdqa ($xa1,&QWP($i+16*1-128,"ebx"));
&movdqa ($xa2,&QWP($i+16*2-128,"ebx"));
&movdqa ($xa3,&QWP($i+16*3-128,"ebx"));
#&movdqa ($xa0,&QWP(16*0-128,"ebx")); # it's there
&movdqa ($xa1,&QWP(16*1-128,"ebx"));
&movdqa ($xa2,&QWP(16*2-128,"ebx"));
&movdqa ($xa3,&QWP(16*3-128,"ebx"));
for($i=0;$i<256;$i+=64) {
&paddd ($xa0,&QWP($i+16*0-128,"ebp")); # accumulate key material
&paddd ($xa1,&QWP($i+16*1-128,"ebp"));
&paddd ($xa2,&QWP($i+16*2-128,"ebp"));
@@ -593,29 +581,25 @@ my ($ap,$bp,$cp,$dp)=map(($_&~3)+(($_-1)&3),($ai,$bi,$ci,$di)); # previous
#($xa2,$xt2)=($xt2,$xa2);
&movdqa (&QWP($i+16*0-128,"ebx"),$xa0);
&movdqu ($xt0,&QWP(64*0-128,$inp)); # load input
&movdqu ($xt1,&QWP(64*1-128,$inp));
&movdqu ($xa2,&QWP(64*2-128,$inp));
&movdqu ($xt3,&QWP(64*3-128,$inp));
&lea ($inp,&QWP($i<192?16:(64*4-16*3),$inp));
&pxor ($xt0,$xa0);
&movdqa ($xa0,&QWP($i+16*4-128,"ebx")) if ($i<192);
&movdqa (&QWP($i+16*1-128,"ebx"),$xa1);
&movdqa (&QWP($i+16*2-128,"ebx"),$xt2);
&movdqa (&QWP($i+16*3-128,"ebx"),$xa3);
&pxor ($xt1,$xa1);
&movdqa ($xa1,&QWP($i+16*5-128,"ebx")) if ($i<192);
&pxor ($xt2,$xa2);
&movdqa ($xa2,&QWP($i+16*6-128,"ebx")) if ($i<192);
&pxor ($xt3,$xa3);
&movdqa ($xa3,&QWP($i+16*7-128,"ebx")) if ($i<192);
&movdqu (&QWP(64*0-128,$out),$xt0); # store output
&movdqu (&QWP(64*1-128,$out),$xt1);
&movdqu (&QWP(64*2-128,$out),$xt2);
&movdqu (&QWP(64*3-128,$out),$xt3);
&lea ($out,&QWP($i<192?16:(64*4-16*3),$out));
}
for($i=0;$i<256;$i+=64) {
my $j = 16*($i/64);
&movdqu ($xa0,&QWP($i+16*0-128,$inp)); # load input
&movdqu ($xa1,&QWP($i+16*1-128,$inp));
&movdqu ($xa2,&QWP($i+16*2-128,$inp));
&movdqu ($xa3,&QWP($i+16*3-128,$inp));
&pxor ($xa0,&QWP($j+64*0-128,"ebx"));
&pxor ($xa1,&QWP($j+64*1-128,"ebx"));
&pxor ($xa2,&QWP($j+64*2-128,"ebx"));
&pxor ($xa3,&QWP($j+64*3-128,"ebx"));
&movdqu (&QWP($i+16*0-128,$out),$xa0); # write output
&movdqu (&QWP($i+16*1-128,$out),$xa1);
&movdqu (&QWP($i+16*2-128,$out),$xa2);
&movdqu (&QWP($i+16*3-128,$out),$xa3);
}
&lea ($inp,&DWP(256,$inp));
&lea ($out,&DWP(256,$out));
&sub ($len,64*4);
&jnc (&label("outer_loop"));
+8 -2
View File
@@ -16,10 +16,13 @@
#include <openssl/chacha.h>
#include <assert.h>
#include <string.h>
#include <openssl/cpu.h>
#include "../internal.h"
#define U8TO32_LITTLE(p) \
(((uint32_t)((p)[0])) | ((uint32_t)((p)[1]) << 8) | \
@@ -36,8 +39,9 @@ void ChaCha20_ctr32(uint8_t *out, const uint8_t *in, size_t in_len,
void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len,
const uint8_t key[32], const uint8_t nonce[12],
uint32_t counter) {
uint32_t counter_nonce[4];
counter_nonce[0] = counter;
assert(!buffers_alias(out, in_len, in, in_len) || in == out);
uint32_t counter_nonce[4]; counter_nonce[0] = counter;
counter_nonce[1] = U8TO32_LITTLE(nonce + 0);
counter_nonce[2] = U8TO32_LITTLE(nonce + 4);
counter_nonce[3] = U8TO32_LITTLE(nonce + 8);
@@ -118,6 +122,8 @@ static void chacha_core(uint8_t output[64], const uint32_t input[16]) {
void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len,
const uint8_t key[32], const uint8_t nonce[12],
uint32_t counter) {
assert(!buffers_alias(out, in_len, in, in_len) || in == out);
uint32_t input[16];
uint8_t buf[64];
size_t todo, i;
+7 -16
View File
@@ -218,25 +218,16 @@ static bool TestChaCha20(size_t len) {
std::unique_ptr<uint8_t[]> buf(new uint8_t[len]);
CRYPTO_chacha_20(buf.get(), kInput, len, kKey, kNonce, kCounter);
if (memcmp(buf.get(), kOutput, len) != 0) {
fprintf(stderr, "Mismatch at length %u.\n", static_cast<unsigned>(len));
fprintf(stderr, "Mismatch at length %zu.\n", len);
return false;
}
// Test in-place at various offsets.
static const size_t kOffsets[] = {
0, 1, 2, 8, 15, 16, 17, 31, 32, 33, 63,
64, 65, 95, 96, 97, 127, 128, 129, 255, 256, 257,
};
for (size_t offset : kOffsets) {
buf.reset(new uint8_t[len + offset]);
memcpy(buf.get() + offset, kInput, len);
CRYPTO_chacha_20(buf.get(), buf.get() + offset, len, kKey, kNonce,
kCounter);
if (memcmp(buf.get(), kOutput, len) != 0) {
fprintf(stderr, "Mismatch at length %u with in-place offset %u.\n",
static_cast<unsigned>(len), static_cast<unsigned>(offset));
return false;
}
// Test in-place.
memcpy(buf.get(), kInput, len);
CRYPTO_chacha_20(buf.get(), buf.get(), len, kKey, kNonce, kCounter);
if (memcmp(buf.get(), kOutput, len) != 0) {
fprintf(stderr, "Mismatch at length %zu, in-place.\n", len);
return false;
}
return true;
+10 -15
View File
@@ -20,6 +20,7 @@
#include <openssl/err.h>
#include "internal.h"
#include "../internal.h"
size_t EVP_AEAD_key_length(const EVP_AEAD *aead) { return aead->key_len; }
@@ -80,21 +81,15 @@ void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx) {
ctx->aead = NULL;
}
/* check_alias returns 0 if |out| points within the buffer determined by |in|
* and |in_len| and 1 otherwise.
*
* When processing, there's only an issue if |out| points within in[:in_len]
* and isn't equal to |in|. If that's the case then writing the output will
* stomp input that hasn't been read yet.
*
* This function checks for that case. */
static int check_alias(const uint8_t *in, size_t in_len, const uint8_t *out) {
if (out <= in) {
return 1;
} else if (in + in_len <= out) {
/* check_alias returns 1 if |out| is compatible with |in| and 0 otherwise. If
* |in| and |out| alias, we require that |in| == |out|. */
static int check_alias(const uint8_t *in, size_t in_len, const uint8_t *out,
size_t out_len) {
if (!buffers_alias(in, in_len, out, out_len)) {
return 1;
}
return 0;
return in == out;
}
int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
@@ -108,7 +103,7 @@ int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
goto error;
}
if (!check_alias(in, in_len, out)) {
if (!check_alias(in, in_len, out, max_out_len)) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT);
goto error;
}
@@ -130,7 +125,7 @@ int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
size_t max_out_len, const uint8_t *nonce,
size_t nonce_len, const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
if (!check_alias(in, in_len, out)) {
if (!check_alias(in, in_len, out, max_out_len)) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT);
goto error;
}
+52 -71
View File
@@ -225,84 +225,65 @@ static bool TestWithAliasedBuffers(const EVP_AEAD *aead) {
return false;
}
// First test with out > in, which we expect to fail.
for (auto offset : offsets) {
if (offset == 0) {
// Will be tested in the next loop.
continue;
}
// Test with out != in which we expect to fail.
std::vector<uint8_t> buffer(2 + valid_encryption_len);
uint8_t *in = buffer.data() + 1;
uint8_t *out1 = buffer.data();
uint8_t *out2 = buffer.data() + 2;
std::vector<uint8_t> buffer(offset + valid_encryption_len);
memcpy(buffer.data(), kPlaintext, sizeof(kPlaintext));
uint8_t *out = buffer.data() + offset;
memcpy(in, kPlaintext, sizeof(kPlaintext));
size_t out_len;
if (EVP_AEAD_CTX_seal(ctx.get(), out1, &out_len,
sizeof(kPlaintext) + max_overhead, nonce.data(),
nonce_len, in, sizeof(kPlaintext), nullptr, 0) ||
EVP_AEAD_CTX_seal(ctx.get(), out2, &out_len,
sizeof(kPlaintext) + max_overhead, nonce.data(),
nonce_len, in, sizeof(kPlaintext), nullptr, 0)) {
fprintf(stderr, "EVP_AEAD_CTX_seal unexpectedly succeeded.\n");
return false;
}
ERR_clear_error();
size_t out_len;
if (!EVP_AEAD_CTX_seal(ctx.get(), out, &out_len,
sizeof(kPlaintext) + max_overhead, nonce.data(),
nonce_len, buffer.data(), sizeof(kPlaintext),
nullptr, 0)) {
// We expect offsets where the output is greater than the input to fail.
ERR_clear_error();
} else {
fprintf(stderr,
"EVP_AEAD_CTX_seal unexpectedly succeeded for offset %u.\n",
static_cast<unsigned>(offset));
return false;
}
memcpy(in, valid_encryption.data(), valid_encryption_len);
if (EVP_AEAD_CTX_open(ctx.get(), out1, &out_len, valid_encryption_len,
nonce.data(), nonce_len, in, valid_encryption_len,
nullptr, 0) ||
EVP_AEAD_CTX_open(ctx.get(), out2, &out_len, valid_encryption_len,
nonce.data(), nonce_len, in, valid_encryption_len,
nullptr, 0)) {
fprintf(stderr, "EVP_AEAD_CTX_open unexpectedly succeeded.\n");
return false;
}
ERR_clear_error();
memcpy(buffer.data(), valid_encryption.data(), valid_encryption_len);
if (!EVP_AEAD_CTX_open(ctx.get(), out, &out_len, valid_encryption_len,
nonce.data(), nonce_len, buffer.data(),
valid_encryption_len, nullptr, 0)) {
// We expect offsets where the output is greater than the input to fail.
ERR_clear_error();
} else {
fprintf(stderr,
"EVP_AEAD_CTX_open unexpectedly succeeded for offset %u.\n",
static_cast<unsigned>(offset));
ERR_print_errors_fp(stderr);
return false;
}
// Test with out == in, which we expect to work.
memcpy(in, kPlaintext, sizeof(kPlaintext));
if (!EVP_AEAD_CTX_seal(ctx.get(), in, &out_len,
sizeof(kPlaintext) + max_overhead, nonce.data(),
nonce_len, in, sizeof(kPlaintext), nullptr, 0)) {
fprintf(stderr, "EVP_AEAD_CTX_seal failed in-place.\n");
return false;
}
// Test with out <= in, which we expect to work.
for (auto offset : offsets) {
std::vector<uint8_t> buffer(offset + valid_encryption_len);
uint8_t *const out = buffer.data();
uint8_t *const in = buffer.data() + offset;
memcpy(in, kPlaintext, sizeof(kPlaintext));
if (out_len != valid_encryption_len ||
memcmp(in, valid_encryption.data(), out_len) != 0) {
fprintf(stderr, "EVP_AEAD_CTX_seal produced bad output in-place.\n");
return false;
}
size_t out_len;
if (!EVP_AEAD_CTX_seal(ctx.get(), out, &out_len,
sizeof(kPlaintext) + max_overhead, nonce.data(),
nonce_len, in, sizeof(kPlaintext), nullptr, 0)) {
fprintf(stderr, "EVP_AEAD_CTX_seal failed for offset -%u.\n",
static_cast<unsigned>(offset));
return false;
}
memcpy(in, valid_encryption.data(), valid_encryption_len);
if (!EVP_AEAD_CTX_open(ctx.get(), in, &out_len, valid_encryption_len,
nonce.data(), nonce_len, in, valid_encryption_len,
nullptr, 0)) {
fprintf(stderr, "EVP_AEAD_CTX_open failed in-place.\n");
return false;
}
if (out_len != valid_encryption_len ||
memcmp(out, valid_encryption.data(), out_len) != 0) {
fprintf(stderr, "EVP_AEAD_CTX_seal produced bad output for offset -%u.\n",
static_cast<unsigned>(offset));
return false;
}
memcpy(in, valid_encryption.data(), valid_encryption_len);
if (!EVP_AEAD_CTX_open(ctx.get(), out, &out_len,
offset + valid_encryption_len, nonce.data(),
nonce_len, in, valid_encryption_len, nullptr, 0)) {
fprintf(stderr, "EVP_AEAD_CTX_open failed for offset -%u.\n",
static_cast<unsigned>(offset));
return false;
}
if (out_len != sizeof(kPlaintext) ||
memcmp(out, kPlaintext, out_len) != 0) {
fprintf(stderr, "EVP_AEAD_CTX_open produced bad output for offset -%u.\n",
static_cast<unsigned>(offset));
return false;
}
if (out_len != sizeof(kPlaintext) ||
memcmp(in, kPlaintext, out_len) != 0) {
fprintf(stderr, "EVP_AEAD_CTX_open produced bad output in-place.\n");
return false;
}
return true;
+1 -1
View File
@@ -284,7 +284,7 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len,
bl = ctx->cipher->block_size;
assert(bl <= (int)sizeof(ctx->buf));
if (i != 0) {
if (i + in_len < bl) {
if (bl - i > in_len) {
memcpy(&ctx->buf[i], in, in_len);
ctx->buf_len += in_len;
*out_len = 0;
+4 -8
View File
@@ -67,9 +67,7 @@
#endif
#if defined(_MSC_VER)
#pragma warning(disable: 4702) /* Unreachable code. */
#endif
OPENSSL_MSVC_PRAGMA(warning(disable: 4702)) /* Unreachable code. */
typedef struct {
union {
@@ -371,17 +369,15 @@ static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
size_t len) {
unsigned num = (unsigned)ctx->num;
EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
if (dat->stream.ctr) {
CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, ctx->iv, ctx->buf, &num,
dat->stream.ctr);
CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, ctx->iv, ctx->buf,
&ctx->num, dat->stream.ctr);
} else {
CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv, ctx->buf, &num,
CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv, ctx->buf, &ctx->num,
dat->block);
}
ctx->num = (int)num;
return 1;
}
-4
View File
@@ -244,10 +244,6 @@ const EVP_AEAD *EVP_aead_chacha20_poly1305(void) {
return &aead_chacha20_poly1305;
}
const EVP_AEAD *EVP_aead_chacha20_poly1305_rfc7539(void) {
return EVP_aead_chacha20_poly1305();
}
static void poly1305_update_old(poly1305_state *ctx, const uint8_t *ad,
size_t ad_len, const uint8_t *ciphertext,
size_t ciphertext_len) {
+1 -1
View File
@@ -1,4 +1,4 @@
# The AES-128-GCM test cases from cipher_test.txt have been merged into this
# The AES-128-GCM test cases from cipher_tests.txt have been merged into this
# file.
KEY: d480429666d48b400633921c5407d1d1
+1 -1
View File
@@ -1,4 +1,4 @@
# The AES-256-GCM test cases from cipher_test.txt have been merged into this
# The AES-256-GCM test cases from cipher_tests.txt have been merged into this
# file.
KEY: e5ac4a32c67e425ac4b143c83c6f161312a97d88d634afdf9f4da5bd35223f01
+39
View File
@@ -177,6 +177,45 @@ void EVP_tls_cbc_copy_mac(uint8_t *out, unsigned md_size,
* + md_size = 256 + 48 (since SHA-384 is the largest hash) = 304. */
assert(rotate_offset <= 304);
/* Below is an SMT-LIB2 verification that the Barrett reductions below are
* correct within this range:
*
* (define-fun barrett (
* (x (_ BitVec 32))
* (mul (_ BitVec 32))
* (shift (_ BitVec 32))
* (divisor (_ BitVec 32)) ) (_ BitVec 32)
* (let ((q (bvsub x (bvmul divisor (bvlshr (bvmul x mul) shift))) ))
* (ite (bvuge q divisor)
* (bvsub q divisor)
* q)))
*
* (declare-fun x () (_ BitVec 32))
*
* (assert (or
* (let (
* (divisor (_ bv20 32))
* (mul (_ bv25 32))
* (shift (_ bv9 32))
* (limit (_ bv853 32)))
*
* (and (bvule x limit) (not (= (bvurem x divisor)
* (barrett x mul shift divisor)))))
*
* (let (
* (divisor (_ bv48 32))
* (mul (_ bv10 32))
* (shift (_ bv9 32))
* (limit (_ bv768 32)))
*
* (and (bvule x limit) (not (= (bvurem x divisor)
* (barrett x mul shift divisor)))))
* ))
*
* (check-sat)
* (get-model)
*/
if (md_size == 16) {
rotate_offset &= 15;
} else if (md_size == 20) {
+6 -1
View File
@@ -288,6 +288,8 @@ static int has_broken_neon(const STRING_PIECE *cpuinfo) {
extern uint32_t OPENSSL_armcap_P;
static int g_has_broken_neon;
void OPENSSL_cpuid_setup(void) {
char *cpuinfo_data;
size_t cpuinfo_len;
@@ -317,7 +319,8 @@ void OPENSSL_cpuid_setup(void) {
}
/* Clear NEON support if known broken. */
if (has_broken_neon(&cpuinfo)) {
g_has_broken_neon = has_broken_neon(&cpuinfo);
if (g_has_broken_neon) {
hwcap &= ~HWCAP_NEON;
}
@@ -352,4 +355,6 @@ void OPENSSL_cpuid_setup(void) {
OPENSSL_free(cpuinfo_data);
}
int CRYPTO_has_broken_NEON(void) { return g_has_broken_neon; }
#endif /* OPENSSL_ARM && !OPENSSL_STATIC_ARMCAP */
+2 -2
View File
@@ -69,10 +69,10 @@
#include <string.h>
#if defined(OPENSSL_WINDOWS)
#pragma warning(push, 3)
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <immintrin.h>
#include <intrin.h>
#pragma warning(pop)
OPENSSL_MSVC_PRAGMA(warning(pop))
#endif
#include "internal.h"
+16 -2
View File
@@ -79,8 +79,6 @@ uint32_t OPENSSL_armcap_P =
#endif
0;
#elif defined(__ARM_NEON__)
uint32_t OPENSSL_armcap_P = ARMV7_NEON;
#else
uint32_t OPENSSL_armcap_P = 0;
#endif
@@ -125,6 +123,22 @@ void CRYPTO_library_init(void) {
#endif
}
int CRYPTO_is_confidential_build(void) {
#if defined(BORINGSSL_CONFIDENTIAL)
return 1;
#else
return 0;
#endif
}
int CRYPTO_has_asm(void) {
#if defined(OPENSSL_NO_ASM)
return 0;
#else
return 1;
#endif
}
const char *SSLeay_version(int unused) {
return "BoringSSL";
}
+21
View File
@@ -1,3 +1,24 @@
/* Copyright (c) 2015, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
/* This code is mostly taken from the ref10 version of Ed25519 in SUPERCOP
* 20141124 (http://bench.cr.yp.to/supercop.html). That code is released as
* public domain but this file has the ISC license just to keep licencing
* simple.
*
* The field functions are shared by Ed25519 and X25519 where possible. */
#include <openssl/curve25519.h>
#include <string.h>
+8 -11
View File
@@ -236,7 +236,6 @@ int DH_generate_key(DH *dh) {
int generate_new_key = 0;
unsigned l;
BN_CTX *ctx = NULL;
BN_MONT_CTX *mont = NULL;
BIGNUM *pub_key = NULL, *priv_key = NULL;
BIGNUM local_priv;
@@ -269,9 +268,8 @@ int DH_generate_key(DH *dh) {
pub_key = dh->pub_key;
}
mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
dh->p, ctx);
if (!mont) {
if (!BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
dh->p, ctx)) {
goto err;
}
@@ -293,7 +291,8 @@ int DH_generate_key(DH *dh) {
}
BN_with_flags(&local_priv, priv_key, BN_FLG_CONSTTIME);
if (!BN_mod_exp_mont(pub_key, dh->g, &local_priv, dh->p, ctx, mont)) {
if (!BN_mod_exp_mont_consttime(pub_key, dh->g, &local_priv, dh->p, ctx,
dh->method_mont_p)) {
goto err;
}
@@ -318,7 +317,6 @@ err:
int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) {
BN_CTX *ctx = NULL;
BN_MONT_CTX *mont = NULL;
BIGNUM *shared_key;
int ret = -1;
int check_result;
@@ -344,9 +342,8 @@ int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) {
goto err;
}
mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
dh->p, ctx);
if (!mont) {
if (!BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock,
dh->p, ctx)) {
goto err;
}
@@ -356,8 +353,8 @@ int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) {
}
BN_with_flags(&local_priv, dh->priv_key, BN_FLG_CONSTTIME);
if (!BN_mod_exp_mont(shared_key, peers_key, &local_priv, dh->p, ctx,
mont)) {
if (!BN_mod_exp_mont_consttime(shared_key, peers_key, &local_priv, dh->p, ctx,
dh->method_mont_p)) {
OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
goto err;
}
+95 -19
View File
@@ -55,30 +55,106 @@
#include <openssl/dh.h>
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
#include <assert.h>
#include <limits.h>
#include "internal.h"
#include <openssl/bn.h>
#include <openssl/bytestring.h>
#include <openssl/err.h>
/* Override the default free and new methods */
static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
void *exarg) {
if (operation == ASN1_OP_NEW_PRE) {
*pval = (ASN1_VALUE *)DH_new();
if (*pval) {
return 2;
}
#include "../bytestring/internal.h"
static int parse_integer(CBS *cbs, BIGNUM **out) {
assert(*out == NULL);
*out = BN_new();
if (*out == NULL) {
return 0;
}
return BN_parse_asn1_unsigned(cbs, *out);
}
static int marshal_integer(CBB *cbb, BIGNUM *bn) {
if (bn == NULL) {
/* A DH object may be missing some components. */
OPENSSL_PUT_ERROR(DH, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
return BN_marshal_asn1(cbb, bn);
}
DH *DH_parse_parameters(CBS *cbs) {
DH *ret = DH_new();
if (ret == NULL) {
return NULL;
}
CBS child;
if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
!parse_integer(&child, &ret->p) ||
!parse_integer(&child, &ret->g)) {
goto err;
}
uint64_t priv_length;
if (CBS_len(&child) != 0) {
if (!CBS_get_asn1_uint64(&child, &priv_length) ||
priv_length > UINT_MAX) {
goto err;
}
ret->priv_length = (unsigned)priv_length;
}
if (CBS_len(&child) != 0) {
goto err;
}
return ret;
err:
OPENSSL_PUT_ERROR(DH, DH_R_DECODE_ERROR);
DH_free(ret);
return NULL;
}
int DH_marshal_parameters(CBB *cbb, const DH *dh) {
CBB child;
if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
!marshal_integer(&child, dh->p) ||
!marshal_integer(&child, dh->g) ||
(dh->priv_length != 0 &&
!CBB_add_asn1_uint64(&child, dh->priv_length)) ||
!CBB_flush(cbb)) {
OPENSSL_PUT_ERROR(DH, DH_R_ENCODE_ERROR);
return 0;
} else if (operation == ASN1_OP_FREE_PRE) {
DH_free((DH *)*pval);
*pval = NULL;
return 2;
}
return 1;
}
ASN1_SEQUENCE_cb(DHparams, dh_cb) = {
ASN1_SIMPLE(DH, p, BIGNUM), ASN1_SIMPLE(DH, g, BIGNUM),
ASN1_OPT(DH, priv_length, ZLONG)} ASN1_SEQUENCE_END_cb(DH, DHparams);
DH *d2i_DHparams(DH **out, const uint8_t **inp, long len) {
if (len < 0) {
return NULL;
}
CBS cbs;
CBS_init(&cbs, *inp, (size_t)len);
DH *ret = DH_parse_parameters(&cbs);
if (ret == NULL) {
return NULL;
}
if (out != NULL) {
DH_free(*out);
*out = ret;
}
*inp = CBS_data(&cbs);
return ret;
}
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams)
int i2d_DHparams(const DH *in, uint8_t **outp) {
CBB cbb;
if (!CBB_init(&cbb, 0) ||
!DH_marshal_parameters(&cbb, in)) {
CBB_cleanup(&cbb);
return -1;
}
return CBB_finish_i2d(&cbb, outp);
}
+92 -1
View File
@@ -62,6 +62,7 @@
#include <vector>
#include <openssl/bn.h>
#include <openssl/bytestring.h>
#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -73,13 +74,15 @@
static bool RunBasicTests();
static bool RunRFC5114Tests();
static bool TestBadY();
static bool TestASN1();
int main(int argc, char *argv[]) {
CRYPTO_library_init();
if (!RunBasicTests() ||
!RunRFC5114Tests() ||
!TestBadY()) {
!TestBadY() ||
!TestASN1()) {
ERR_print_errors_fp(stderr);
return 1;
}
@@ -533,3 +536,91 @@ static bool TestBadY() {
return true;
}
static bool BIGNUMEqualsHex(const BIGNUM *bn, const char *hex) {
BIGNUM *hex_bn = NULL;
if (!BN_hex2bn(&hex_bn, hex)) {
return false;
}
ScopedBIGNUM free_hex_bn(hex_bn);
return BN_cmp(bn, hex_bn) == 0;
}
static bool TestASN1() {
// kParams are a set of Diffie-Hellman parameters generated with
// openssl dhparam 256
static const uint8_t kParams[] = {
0x30, 0x26, 0x02, 0x21, 0x00, 0xd7, 0x20, 0x34, 0xa3, 0x27,
0x4f, 0xdf, 0xbf, 0x04, 0xfd, 0x24, 0x68, 0x25, 0xb6, 0x56,
0xd8, 0xab, 0x2a, 0x41, 0x2d, 0x74, 0x0a, 0x52, 0x08, 0x7c,
0x40, 0x71, 0x4e, 0xd2, 0x57, 0x93, 0x13, 0x02, 0x01, 0x02,
};
CBS cbs;
CBS_init(&cbs, kParams, sizeof(kParams));
ScopedDH dh(DH_parse_parameters(&cbs));
if (!dh || CBS_len(&cbs) != 0 ||
!BIGNUMEqualsHex(
dh->p,
"d72034a3274fdfbf04fd246825b656d8ab2a412d740a52087c40714ed2579313") ||
!BIGNUMEqualsHex(dh->g, "2") || dh->priv_length != 0) {
return false;
}
ScopedCBB cbb;
uint8_t *der;
size_t der_len;
if (!CBB_init(cbb.get(), 0) ||
!DH_marshal_parameters(cbb.get(), dh.get()) ||
!CBB_finish(cbb.get(), &der, &der_len)) {
return false;
}
ScopedOpenSSLBytes free_der(der);
if (der_len != sizeof(kParams) || memcmp(der, kParams, der_len) != 0) {
return false;
}
// kParamsDSA are a set of Diffie-Hellman parameters generated with
// openssl dhparam 256 -dsaparam
static const uint8_t kParamsDSA[] = {
0x30, 0x81, 0x89, 0x02, 0x41, 0x00, 0x93, 0xf3, 0xc1, 0x18, 0x01, 0xe6,
0x62, 0xb6, 0xd1, 0x46, 0x9a, 0x2c, 0x72, 0xea, 0x31, 0xd9, 0x18, 0x10,
0x30, 0x28, 0x63, 0xe2, 0x34, 0x7d, 0x80, 0xca, 0xee, 0x82, 0x2b, 0x19,
0x3c, 0x19, 0xbb, 0x42, 0x83, 0x02, 0x70, 0xdd, 0xdb, 0x8c, 0x03, 0xab,
0xe9, 0x9c, 0xc4, 0x00, 0x4d, 0x70, 0x5f, 0x52, 0x03, 0x31, 0x2c, 0xa4,
0x67, 0x34, 0x51, 0x95, 0x2a, 0xac, 0x11, 0xe2, 0x6a, 0x55, 0x02, 0x40,
0x44, 0xc8, 0x10, 0x53, 0x44, 0x32, 0x31, 0x63, 0xd8, 0xd1, 0x8c, 0x75,
0xc8, 0x98, 0x53, 0x3b, 0x5b, 0x4a, 0x2a, 0x0a, 0x09, 0xe7, 0xd0, 0x3c,
0x53, 0x72, 0xa8, 0x6b, 0x70, 0x41, 0x9c, 0x26, 0x71, 0x44, 0xfc, 0x7f,
0x08, 0x75, 0xe1, 0x02, 0xab, 0x74, 0x41, 0xe8, 0x2a, 0x3d, 0x3c, 0x26,
0x33, 0x09, 0xe4, 0x8b, 0xb4, 0x41, 0xec, 0xa6, 0xa8, 0xba, 0x1a, 0x07,
0x8a, 0x77, 0xf5, 0x5f, 0x02, 0x02, 0x00, 0xa0,
};
CBS_init(&cbs, kParamsDSA, sizeof(kParamsDSA));
dh.reset(DH_parse_parameters(&cbs));
if (!dh || CBS_len(&cbs) != 0 ||
!BIGNUMEqualsHex(dh->p,
"93f3c11801e662b6d1469a2c72ea31d91810302863e2347d80caee8"
"22b193c19bb42830270dddb8c03abe99cc4004d705f5203312ca467"
"3451952aac11e26a55") ||
!BIGNUMEqualsHex(dh->g,
"44c8105344323163d8d18c75c898533b5b4a2a0a09e7d03c5372a86"
"b70419c267144fc7f0875e102ab7441e82a3d3c263309e48bb441ec"
"a6a8ba1a078a77f55f") ||
dh->priv_length != 160) {
return false;
}
if (!CBB_init(cbb.get(), 0) ||
!DH_marshal_parameters(cbb.get(), dh.get()) ||
!CBB_finish(cbb.get(), &der, &der_len)) {
return false;
}
ScopedOpenSSLBytes free_der2(der);
if (der_len != sizeof(kParamsDSA) || memcmp(der, kParamsDSA, der_len) != 0) {
return false;
}
return true;
}
+2 -2
View File
@@ -231,11 +231,11 @@ const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx) {
return ctx->digest;
}
unsigned EVP_MD_CTX_size(const EVP_MD_CTX *ctx) {
size_t EVP_MD_CTX_size(const EVP_MD_CTX *ctx) {
return EVP_MD_size(EVP_MD_CTX_md(ctx));
}
unsigned EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx) {
size_t EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx) {
return EVP_MD_block_size(EVP_MD_CTX_md(ctx));
}
-66
View File
@@ -1,66 +0,0 @@
/* Copied from Richard Levitte's (richard@levitte.org) LP library. All
* symbol names have been changed, with permission from the author. */
/* $LP: LPlib/source/LPdir.h,v 1.1 2004/06/14 08:56:04 _cvs_levitte Exp $ */
/*
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef OPENSSL_HEADER_DIRECTORY_H
#define OPENSSL_HEADER_DIRECTORY_H
#include <openssl/base.h>
#if defined(__cplusplus)
extern "C" {
#endif
/* Directory functions abstract the O/S specific operations for opening and
* reading directories in the filesystem. */
/* OPENSSL_dir_context_st is an opaque structure that represents an open
* directory and a position in that directory. */
typedef struct OPENSSL_dir_context_st OPENSSL_DIR_CTX;
/* OPENSSL_DIR_read reads a single filename from |ctx|. On the first call,
* |directory| must be given and |*ctx| must be NULL. Subsequent calls with the
* same |*ctx| will return subsequent file names until it returns NULL to
* indicate EOF. The strings returned reference a buffer internal to the
* |OPENSSL_DIR_CTX| and will be overridden by subsequent calls. */
OPENSSL_EXPORT const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx,
const char *directory);
/* OPENSSL_DIR_end closes |*ctx|. It returns one on success and zero on
* error. */
OPENSSL_EXPORT int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx);
#if defined(__cplusplus)
} /* extern C */
#endif
#endif /* OPENSSL_HEADER_DIRECTORY_H */
-108
View File
@@ -1,108 +0,0 @@
/* $LP: LPlib/source/LPdir_unix.c,v 1.11 2004/09/23 22:07:22 _cvs_levitte Exp $ */
/*
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
#if !defined(_POSIX_C_SOURCE)
#define _POSIX_C_SOURCE 201409 /* for readdir_r */
#endif
#include "directory.h"
#if !defined(OPENSSL_WINDOWS)
#include <dirent.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#if defined(OPENSSL_PNACL)
/* pnacl doesn't include readdir_r! So we do the best we can. */
int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result) {
errno = 0;
*result = readdir(dirp);
if (*result != NULL) {
return 0;
}
if (errno) {
return 1;
}
return 0;
}
#endif
struct OPENSSL_dir_context_st {
DIR *dir;
struct dirent dirent;
};
const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, const char *directory) {
struct dirent *dirent;
if (ctx == NULL || directory == NULL) {
errno = EINVAL;
return NULL;
}
errno = 0;
if (*ctx == NULL) {
*ctx = malloc(sizeof(OPENSSL_DIR_CTX));
if (*ctx == NULL) {
errno = ENOMEM;
return 0;
}
memset(*ctx, 0, sizeof(OPENSSL_DIR_CTX));
(*ctx)->dir = opendir(directory);
if ((*ctx)->dir == NULL) {
int save_errno = errno; /* Probably not needed, but I'm paranoid */
free(*ctx);
*ctx = NULL;
errno = save_errno;
return 0;
}
}
if (readdir_r((*ctx)->dir, &(*ctx)->dirent, &dirent) != 0 ||
dirent == NULL) {
return 0;
}
return (*ctx)->dirent.d_name;
}
int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx) {
if (ctx != NULL && *ctx != NULL) {
int r = closedir((*ctx)->dir);
free(*ctx);
*ctx = NULL;
return r == 0;
}
errno = EINVAL;
return 0;
}
#endif /* !OPENSSL_WINDOWS */
-144
View File
@@ -1,144 +0,0 @@
/* $LP: LPlib/source/LPdir_win.c,v 1.10 2004/08/26 13:36:05 _cvs_levitte Exp $ */
/*
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "directory.h"
#if defined(OPENSSL_WINDOWS)
#pragma warning(push, 3)
#include <windows.h>
#pragma warning(pop)
#include <errno.h>
#include <string.h>
#include <tchar.h>
#ifndef NAME_MAX
#define NAME_MAX 255
#endif
#include <openssl/mem.h>
struct OPENSSL_dir_context_st {
WIN32_FIND_DATA ctx;
HANDLE handle;
char entry_name[NAME_MAX + 1];
};
const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, const char *directory) {
if (ctx == NULL || directory == NULL) {
errno = EINVAL;
return 0;
}
errno = 0;
if (*ctx == NULL) {
*ctx = malloc(sizeof(OPENSSL_DIR_CTX));
if (*ctx == NULL) {
errno = ENOMEM;
return 0;
}
memset(*ctx, 0, sizeof(OPENSSL_DIR_CTX));
if (sizeof(TCHAR) != sizeof(char)) {
TCHAR *wdir = NULL;
/* len_0 denotes string length *with* trailing 0 */
size_t index = 0, len_0 = strlen(directory) + 1;
wdir = (TCHAR *)malloc(len_0 * sizeof(TCHAR));
if (wdir == NULL) {
free(*ctx);
*ctx = NULL;
errno = ENOMEM;
return 0;
}
if (!MultiByteToWideChar(CP_ACP, 0, directory, len_0, (WCHAR *)wdir,
len_0)) {
for (index = 0; index < len_0; index++) {
wdir[index] = (TCHAR)directory[index];
}
}
(*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx);
free(wdir);
} else {
(*ctx)->handle = FindFirstFile((TCHAR *)directory, &(*ctx)->ctx);
}
if ((*ctx)->handle == INVALID_HANDLE_VALUE) {
free(*ctx);
*ctx = NULL;
errno = EINVAL;
return 0;
}
} else {
if (FindNextFile((*ctx)->handle, &(*ctx)->ctx) == FALSE) {
return 0;
}
}
if (sizeof(TCHAR) != sizeof(char)) {
TCHAR *wdir = (*ctx)->ctx.cFileName;
size_t index, len_0 = 0;
while (wdir[len_0] && len_0 < (sizeof((*ctx)->entry_name) - 1)) {
len_0++;
}
len_0++;
if (!WideCharToMultiByte(CP_ACP, 0, (WCHAR *)wdir, len_0,
(*ctx)->entry_name, sizeof((*ctx)->entry_name),
NULL, 0)) {
for (index = 0; index < len_0; index++) {
(*ctx)->entry_name[index] = (char)wdir[index];
}
}
} else {
strncpy((*ctx)->entry_name, (const char *)(*ctx)->ctx.cFileName,
sizeof((*ctx)->entry_name) - 1);
}
(*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0';
return (*ctx)->entry_name;
}
int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx) {
if (ctx != NULL && *ctx != NULL) {
FindClose((*ctx)->handle);
free(*ctx);
*ctx = NULL;
return 1;
}
errno = EINVAL;
return 0;
}
#endif /* OPENSSL_WINDOWS */
+8 -9
View File
@@ -591,7 +591,6 @@ int DSA_do_check_signature(int *out_valid, const uint8_t *digest,
size_t digest_len, DSA_SIG *sig, const DSA *dsa) {
BN_CTX *ctx;
BIGNUM u1, u2, t1;
BN_MONT_CTX *mont = NULL;
int ret = 0;
unsigned i;
@@ -662,15 +661,14 @@ int DSA_do_check_signature(int *out_valid, const uint8_t *digest,
goto err;
}
mont = BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
(CRYPTO_MUTEX *)&dsa->method_mont_p_lock,
dsa->p, ctx);
if (!mont) {
if (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
(CRYPTO_MUTEX *)&dsa->method_mont_p_lock, dsa->p,
ctx)) {
goto err;
}
if (!BN_mod_exp2_mont(&t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx,
mont)) {
dsa->method_mont_p)) {
goto err;
}
@@ -823,9 +821,9 @@ int DSA_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv,
BN_set_flags(&k, BN_FLG_CONSTTIME);
if (BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
(CRYPTO_MUTEX *)&dsa->method_mont_p_lock, dsa->p,
ctx) == NULL) {
if (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p,
(CRYPTO_MUTEX *)&dsa->method_mont_p_lock, dsa->p,
ctx)) {
goto err;
}
@@ -847,6 +845,7 @@ int DSA_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv,
goto err;
}
BN_set_flags(&kq, BN_FLG_CONSTTIME);
K = &kq;
if (!BN_mod_exp_mont(r, dsa->g, K, dsa->p, ctx, dsa->method_mont_p)) {
+43 -33
View File
@@ -219,15 +219,12 @@ static int ec_GFp_mont_point_get_affine_coordinates(const EC_GROUP *group,
const EC_POINT *point,
BIGNUM *x, BIGNUM *y,
BN_CTX *ctx) {
BN_CTX *new_ctx = NULL;
BIGNUM *Z, *Z_1, *Z_2, *Z_3;
int ret = 0;
if (EC_POINT_is_at_infinity(group, point)) {
OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
return 0;
}
BN_CTX *new_ctx = NULL;
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL) {
@@ -235,52 +232,65 @@ static int ec_GFp_mont_point_get_affine_coordinates(const EC_GROUP *group,
}
}
int ret = 0;
BN_CTX_start(ctx);
Z = BN_CTX_get(ctx);
Z_1 = BN_CTX_get(ctx);
Z_2 = BN_CTX_get(ctx);
Z_3 = BN_CTX_get(ctx);
if (Z == NULL || Z_1 == NULL || Z_2 == NULL || Z_3 == NULL) {
goto err;
}
/* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */
if (!group->meth->field_decode(group, Z, &point->Z, ctx)) {
goto err;
}
if (BN_is_one(Z)) {
if (x != NULL && !group->meth->field_decode(group, x, &point->X, ctx)) {
if (BN_cmp(&point->Z, &group->one) == 0) {
/* |point| is already affine. */
if (x != NULL && !BN_from_montgomery(x, &point->X, group->mont, ctx)) {
goto err;
}
if (y != NULL && !group->meth->field_decode(group, y, &point->Y, ctx)) {
if (y != NULL && !BN_from_montgomery(y, &point->Y, group->mont, ctx)) {
goto err;
}
} else {
if (!BN_mod_inverse(Z_1, Z, &group->field, ctx)) {
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
/* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */
BIGNUM *Z_1 = BN_CTX_get(ctx);
BIGNUM *Z_2 = BN_CTX_get(ctx);
BIGNUM *Z_3 = BN_CTX_get(ctx);
if (Z_1 == NULL ||
Z_2 == NULL ||
Z_3 == NULL) {
goto err;
}
if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) {
/* The straightforward way to calculate the inverse of a Montgomery-encoded
* value where the result is Montgomery-encoded is:
*
* |BN_from_montgomery| + |BN_mod_inverse| + |BN_to_montgomery|.
*
* This is equivalent, but more efficient, because |BN_from_montgomery|
* is more efficient (at least in theory) than |BN_to_montgomery|, since it
* doesn't have to do the multiplication before the reduction. */
if (!BN_from_montgomery(Z_1, &point->Z, group->mont, ctx) ||
!BN_from_montgomery(Z_1, Z_1, group->mont, ctx) ||
!BN_mod_inverse(Z_1, Z_1, &group->field, ctx)) {
goto err;
}
/* in the Montgomery case, field_mul will cancel out Montgomery factor in
* X: */
if (x != NULL && !group->meth->field_mul(group, x, &point->X, Z_2, ctx)) {
if (!BN_mod_mul_montgomery(Z_2, Z_1, Z_1, group->mont, ctx)) {
goto err;
}
/* Instead of using |BN_from_montgomery| to convert the |x| coordinate
* and then calling |BN_from_montgomery| again to convert the |y|
* coordinate below, convert the common factor |Z_2| once now, saving one
* reduction. */
if (!BN_from_montgomery(Z_2, Z_2, group->mont, ctx)) {
goto err;
}
if (x != NULL) {
if (!BN_mod_mul_montgomery(x, &point->X, Z_2, group->mont, ctx)) {
goto err;
}
}
if (y != NULL) {
if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) {
goto err;
}
/* in the Montgomery case, field_mul will cancel out Montgomery factor in
* Y: */
if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) {
if (!BN_mod_mul_montgomery(Z_3, Z_2, Z_1, group->mont, ctx) ||
!BN_mod_mul_montgomery(y, &point->Y, Z_3, group->mont, ctx)) {
goto err;
}
}
+22 -16
View File
@@ -328,8 +328,7 @@ static void felem_shrink(smallfelem out, const felem in) {
* conditionally subtract kPrime if tmp[3] is large enough. */
high = tmp[3] >> 64;
/* As tmp[3] < 2^65, high is either 1 or 0 */
high <<= 63;
high >>= 63;
high = ~(high - 1);
/* high is:
* all ones if the high word of tmp[3] is 1
* all zeros if the high word of tmp[3] if 0 */
@@ -1561,22 +1560,29 @@ static int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
felem_inv(z2, z1);
felem_square(tmp, z2);
felem_reduce(z1, tmp);
felem_mul(tmp, x_in, z1);
felem_reduce(x_in, tmp);
felem_contract(x_out, x_in);
if (x != NULL && !smallfelem_to_BN(x, x_out)) {
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
return 0;
if (x != NULL) {
felem_mul(tmp, x_in, z1);
felem_reduce(x_in, tmp);
felem_contract(x_out, x_in);
if (!smallfelem_to_BN(x, x_out)) {
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
return 0;
}
}
felem_mul(tmp, z1, z2);
felem_reduce(z1, tmp);
felem_mul(tmp, y_in, z1);
felem_reduce(y_in, tmp);
felem_contract(y_out, y_in);
if (y != NULL && !smallfelem_to_BN(y, y_out)) {
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
return 0;
if (y != NULL) {
felem_mul(tmp, z1, z2);
felem_reduce(z1, tmp);
felem_mul(tmp, y_in, z1);
felem_reduce(y_in, tmp);
felem_contract(y_out, y_in);
if (!smallfelem_to_BN(y, y_out)) {
OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
return 0;
}
}
return 1;
}
+10 -6
View File
@@ -502,8 +502,6 @@ static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point,
BIGNUM *x, BIGNUM *y, BN_CTX *ctx) {
BN_ULONG z_inv2[P256_LIMBS];
BN_ULONG z_inv3[P256_LIMBS];
BN_ULONG x_aff[P256_LIMBS];
BN_ULONG y_aff[P256_LIMBS];
BN_ULONG point_x[P256_LIMBS], point_y[P256_LIMBS], point_z[P256_LIMBS];
if (EC_POINT_is_at_infinity(group, point)) {
@@ -520,7 +518,12 @@ static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point,
ecp_nistz256_mod_inverse(z_inv3, point_z);
ecp_nistz256_sqr_mont(z_inv2, z_inv3);
ecp_nistz256_mul_mont(x_aff, z_inv2, point_x);
/* Instead of using |ecp_nistz256_from_mont| to convert the |x| coordinate
* and then calling |ecp_nistz256_from_mont| again to convert the |y|
* coordinate below, convert the common factor |z_inv2| once now, saving one
* reduction. */
ecp_nistz256_from_mont(z_inv2, z_inv2);
if (x != NULL) {
if (bn_wexpand(x, P256_LIMBS) == NULL) {
@@ -528,19 +531,20 @@ static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point,
return 0;
}
x->top = P256_LIMBS;
ecp_nistz256_from_mont(x->d, x_aff);
x->neg = 0;
ecp_nistz256_mul_mont(x->d, z_inv2, point_x);
bn_correct_top(x);
}
if (y != NULL) {
ecp_nistz256_mul_mont(z_inv3, z_inv3, z_inv2);
ecp_nistz256_mul_mont(y_aff, z_inv3, point_y);
if (bn_wexpand(y, P256_LIMBS) == NULL) {
OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return 0;
}
y->top = P256_LIMBS;
ecp_nistz256_from_mont(y->d, y_aff);
y->neg = 0;
ecp_nistz256_mul_mont(y->d, z_inv3, point_y);
bn_correct_top(y);
}
-9
View File
@@ -79,10 +79,6 @@ int ECDSA_verify(int type, const uint8_t *digest, size_t digest_len,
int ret = 0;
uint8_t *der = NULL;
if (eckey->ecdsa_meth && eckey->ecdsa_meth->verify) {
return eckey->ecdsa_meth->verify(digest, digest_len, sig, sig_len, eckey);
}
/* Decode the ECDSA signature. */
s = ECDSA_SIG_from_bytes(sig, sig_len);
if (s == NULL) {
@@ -148,11 +144,6 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
const EC_GROUP *group;
const EC_POINT *pub_key;
if (eckey->ecdsa_meth && eckey->ecdsa_meth->verify) {
OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED);
return 0;
}
/* check input values */
if ((group = EC_KEY_get0_group(eckey)) == NULL ||
(pub_key = EC_KEY_get0_public_key(eckey)) == NULL ||
+2
View File
@@ -1,4 +1,6 @@
DH,100,BAD_GENERATOR
DH,104,DECODE_ERROR
DH,105,ENCODE_ERROR
DH,101,INVALID_PUBKEY
DH,102,MODULUS_TOO_LARGE
DH,103,NO_PRIVATE_VALUE
+3 -3
View File
@@ -114,9 +114,9 @@
#include <string.h>
#if defined(OPENSSL_WINDOWS)
#pragma warning(push, 3)
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <windows.h>
#pragma warning(pop)
OPENSSL_MSVC_PRAGMA(warning(pop))
#endif
#include <openssl/mem.h>
@@ -325,7 +325,7 @@ int ERR_get_next_error_library(void) {
CRYPTO_STATIC_MUTEX_lock_write(&global_next_library_mutex);
ret = global_next_library++;
CRYPTO_STATIC_MUTEX_unlock(&global_next_library_mutex);
CRYPTO_STATIC_MUTEX_unlock_write(&global_next_library_mutex);
return ret;
}
+8 -1
View File
@@ -18,6 +18,7 @@ import (
"bufio"
"bytes"
"errors"
"flag"
"fmt"
"io"
"os"
@@ -26,6 +27,8 @@ import (
"strings"
)
var verbose = flag.Bool("verbose", false, "If true, prints a status message at the end.")
// libraryNames must be kept in sync with the enum in err.h. The generated code
// will contain static assertions to enforce this.
var libraryNames = []string{
@@ -138,7 +141,9 @@ type stringWriter interface {
func (st *stringList) WriteTo(out stringWriter, name string) {
list := st.buildList()
fmt.Fprintf(os.Stderr, "%s: %d bytes of list and %d bytes of string data.\n", name, 4*len(list), len(st.stringData))
if *verbose {
fmt.Fprintf(os.Stderr, "%s: %d bytes of list and %d bytes of string data.\n", name, 4*len(list), len(st.stringData))
}
values := "kOpenSSL" + name + "Values"
out.WriteString("const uint32_t " + values + "[] = {\n")
@@ -215,6 +220,8 @@ func (e *errorData) readErrorDataFile(filename string) error {
}
func main() {
flag.Parse()
e := &errorData{
reasons: newStringList(),
libraryMap: make(map[string]uint32),
+1
View File
@@ -17,6 +17,7 @@ X509,115,KEY_TYPE_MISMATCH
X509,116,KEY_VALUES_MISMATCH
X509,117,LOADING_CERT_DIR
X509,118,LOADING_DEFAULTS
X509,135,NAME_TOO_LONG
X509,119,NEWER_CRL_NOT_NEWER
X509,120,NOT_PKCS7_SIGNED_DATA
X509,121,NO_CERTIFICATES_INCLUDED
+2
View File
@@ -356,6 +356,8 @@ int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) {
void OpenSSL_add_all_algorithms(void) {}
void OPENSSL_add_all_algorithms_conf(void) {}
void OpenSSL_add_all_ciphers(void) {}
void OpenSSL_add_all_digests(void) {}
+5 -8
View File
@@ -51,30 +51,27 @@
* ====================================================================
*/
#include <openssl/evp.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable: 4702)
#endif
OPENSSL_MSVC_PRAGMA(warning(push))
OPENSSL_MSVC_PRAGMA(warning(disable: 4702))
#include <map>
#include <string>
#include <utility>
#include <vector>
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
OPENSSL_MSVC_PRAGMA(warning(pop))
#include <openssl/bytestring.h>
#include <openssl/crypto.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include "../test/file_test.h"
#include "../test/scoped_types.h"
+5
View File
@@ -54,6 +54,11 @@ PublicKey = P-256-SPKI
Input = 3082014b3082010306072a8648ce3d02013081f7020101302c06072a8648ce3d0101022100ffffffff00000001000000000000000000000000ffffffffffffffffffffffff305b0420ffffffff00000001000000000000000000000000fffffffffffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b031500c49d360886e704936a6678e1139d26b7819f7e900441046b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551020101034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
Error = DECODE_ERROR
# The same as above, but with trailing data after the curve name.
PublicKey = P-256-SPKI
Input = 305b301506072a8648ce3d020106082a8648ce3d0301070500034200042c150f429ce70f216c252cf5e062ce1f639cd5d165c7f89424072c27197d78b33b920e95cdb664e990dcf0cfea0d94e2a8e6af9d0e58056e653104925b9fe6c9
Error = DECODE_ERROR
# A DSA private key.
PrivateKey = DSA-1024
Type = DSA
+4 -3
View File
@@ -93,14 +93,15 @@ static int eckey_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) {
/* See RFC 5480, section 2. */
/* The parameters are a named curve. */
EC_POINT *point = NULL;
EC_KEY *eckey = NULL;
EC_GROUP *group = EC_KEY_parse_curve_name(params);
if (group == NULL || CBS_len(params) != 0) {
OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
return 0;
goto err;
}
EC_POINT *point = NULL;
EC_KEY *eckey = EC_KEY_new();
eckey = EC_KEY_new();
if (eckey == NULL || !EC_KEY_set_group(eckey, group)) {
goto err;
}
+2 -2
View File
@@ -163,7 +163,7 @@ int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index,
ret = 1;
err:
CRYPTO_STATIC_MUTEX_unlock(&ex_data_class->lock);
CRYPTO_STATIC_MUTEX_unlock_write(&ex_data_class->lock);
return ret;
}
@@ -217,7 +217,7 @@ static int get_func_pointers(STACK_OF(CRYPTO_EX_DATA_FUNCS) **out,
if (n > 0) {
*out = sk_CRYPTO_EX_DATA_FUNCS_dup(ex_data_class->meth);
}
CRYPTO_STATIC_MUTEX_unlock(&ex_data_class->lock);
CRYPTO_STATIC_MUTEX_unlock_read(&ex_data_class->lock);
if (n > 0 && *out == NULL) {
OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE);
+39 -18
View File
@@ -21,21 +21,49 @@
#include <openssl/hmac.h>
int HKDF(uint8_t *out_key, size_t out_len,
const EVP_MD *digest,
const uint8_t *secret, size_t secret_len,
const uint8_t *salt, size_t salt_len,
const uint8_t *info, size_t info_len) {
int HKDF(uint8_t *out_key, size_t out_len, const EVP_MD *digest,
const uint8_t *secret, size_t secret_len, const uint8_t *salt,
size_t salt_len, const uint8_t *info, size_t info_len) {
/* https://tools.ietf.org/html/rfc5869#section-2 */
uint8_t prk[EVP_MAX_MD_SIZE];
size_t prk_len;
if (!HKDF_extract(prk, &prk_len, digest, secret, secret_len, salt,
salt_len) ||
!HKDF_expand(out_key, out_len, digest, prk, prk_len, info, info_len)) {
return 0;
}
return 1;
}
int HKDF_extract(uint8_t *out_key, size_t *out_len, const EVP_MD *digest,
const uint8_t *secret, size_t secret_len, const uint8_t *salt,
size_t salt_len) {
/* https://tools.ietf.org/html/rfc5869#section-2.2 */
const size_t digest_len = EVP_MD_size(digest);
uint8_t prk[EVP_MAX_MD_SIZE], previous[EVP_MAX_MD_SIZE];
size_t n, done = 0;
unsigned i, prk_len;
int ret = 0;
HMAC_CTX hmac;
/* If salt is not given, HashLength zeros are used. However, HMAC does that
* internally already so we can ignore it.*/
unsigned len;
if (HMAC(digest, salt, salt_len, secret, secret_len, out_key, &len) == NULL) {
OPENSSL_PUT_ERROR(HKDF, ERR_R_HMAC_LIB);
return 0;
}
*out_len = len;
assert(*out_len == EVP_MD_size(digest));
return 1;
}
int HKDF_expand(uint8_t *out_key, size_t out_len, const EVP_MD *digest,
uint8_t *prk, size_t prk_len, const uint8_t *info,
size_t info_len) {
/* https://tools.ietf.org/html/rfc5869#section-2.3 */
const size_t digest_len = EVP_MD_size(digest);
uint8_t previous[EVP_MAX_MD_SIZE];
size_t n, done = 0;
unsigned i;
int ret = 0;
HMAC_CTX hmac;
/* Expand key material to desired length. */
n = (out_len + digest_len - 1) / digest_len;
@@ -45,13 +73,6 @@ int HKDF(uint8_t *out_key, size_t out_len,
}
HMAC_CTX_init(&hmac);
/* Extract input keying material into pseudorandom key |prk|. */
if (HMAC(digest, salt, salt_len, secret, secret_len, prk, &prk_len) == NULL) {
goto out;
}
assert(prk_len == digest_len);
if (!HMAC_Init_ex(&hmac, prk, prk_len, digest, NULL)) {
goto out;
}
+60 -5
View File
@@ -31,6 +31,8 @@ typedef struct {
const size_t salt_len;
const uint8_t info[80];
const size_t info_len;
const uint8_t prk[EVP_MAX_MD_SIZE];
const size_t prk_len;
const size_t out_len;
const uint8_t out[82];
} hkdf_test_vector_t;
@@ -50,6 +52,11 @@ static const hkdf_test_vector_t kTests[] = {
{
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
}, 10,
{
0x07, 0x77, 0x09, 0x36, 0x2c, 0x2e, 0x32, 0xdf, 0x0d, 0xdc, 0x3f, 0x0d,
0xc4, 0x7b, 0xba, 0x63, 0x90, 0xb6, 0xc7, 0x3b, 0xb5, 0x0f, 0x9c, 0x31,
0x22, 0xec, 0x84, 0x4a, 0xd7, 0xc2, 0xb3, 0xe5,
}, 32,
42, {
0x3c, 0xb2, 0x5f, 0x25, 0xfa, 0xac, 0xd5, 0x7a, 0x90, 0x43, 0x4f, 0x64,
0xd0, 0x36, 0x2f, 0x2a, 0x2d, 0x2d, 0x0a, 0x90, 0xcf, 0x1a, 0x5a, 0x4c,
@@ -86,6 +93,11 @@ static const hkdf_test_vector_t kTests[] = {
0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
}, 80,
{
0x06, 0xa6, 0xb8, 0x8c, 0x58, 0x53, 0x36, 0x1a, 0x06, 0x10, 0x4c, 0x9c,
0xeb, 0x35, 0xb4, 0x5c, 0xef, 0x76, 0x00, 0x14, 0x90, 0x46, 0x71, 0x01,
0x4a, 0x19, 0x3f, 0x40, 0xc1, 0x5f, 0xc2, 0x44,
}, 32,
82, {
0xb1, 0x1e, 0x39, 0x8d, 0xc8, 0x03, 0x27, 0xa1, 0xc8, 0xe7, 0xf7, 0x8c,
0x59, 0x6a, 0x49, 0x34, 0x4f, 0x01, 0x2e, 0xda, 0x2d, 0x4e, 0xfa, 0xd8,
@@ -108,6 +120,11 @@ static const hkdf_test_vector_t kTests[] = {
{
0,
}, 0,
{
0x19, 0xef, 0x24, 0xa3, 0x2c, 0x71, 0x7b, 0x16, 0x7f, 0x33, 0xa9, 0x1d,
0x6f, 0x64, 0x8b, 0xdf, 0x96, 0x59, 0x67, 0x76, 0xaf, 0xdb, 0x63, 0x77,
0xac, 0x43, 0x4c, 0x1c, 0x29, 0x3c, 0xcb, 0x04
}, 32,
42, {
0x8d, 0xa4, 0xe7, 0x75, 0xa5, 0x63, 0xc1, 0x8f, 0x71, 0x5f, 0x80, 0x2a,
0x06, 0x3c, 0x5a, 0x31, 0xb8, 0xa1, 0x1f, 0x5c, 0x5e, 0xe1, 0x87, 0x9e,
@@ -127,6 +144,10 @@ static const hkdf_test_vector_t kTests[] = {
{
0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
}, 10,
{
0x9b, 0x6c, 0x18, 0xc4, 0x32, 0xa7, 0xbf, 0x8f, 0x0e, 0x71, 0xc8, 0xeb,
0x88, 0xf4, 0xb3, 0x0b, 0xaa, 0x2b, 0xa2, 0x43
}, 20,
42, {
0x08, 0x5a, 0x01, 0xea, 0x1b, 0x10, 0xf3, 0x69, 0x33, 0x06, 0x8b, 0x56,
0xef, 0xa5, 0xad, 0x81, 0xa4, 0xf1, 0x4b, 0x82, 0x2f, 0x5b, 0x09, 0x15,
@@ -163,6 +184,10 @@ static const hkdf_test_vector_t kTests[] = {
0xec, 0xed, 0xee, 0xef, 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
}, 80,
{
0x8a, 0xda, 0xe0, 0x9a, 0x2a, 0x30, 0x70, 0x59, 0x47, 0x8d, 0x30, 0x9b,
0x26, 0xc4, 0x11, 0x5a, 0x22, 0x4c, 0xfa, 0xf6,
}, 20,
82, {
0x0b, 0xd7, 0x70, 0xa7, 0x4d, 0x11, 0x60, 0xf7, 0xc9, 0xf1, 0x2c, 0xd5,
0x91, 0x2a, 0x06, 0xeb, 0xff, 0x6a, 0xdc, 0xae, 0x89, 0x9d, 0x92, 0x19,
@@ -185,6 +210,10 @@ static const hkdf_test_vector_t kTests[] = {
{
0,
}, 0,
{
0xda, 0x8c, 0x8a, 0x73, 0xc7, 0xfa, 0x77, 0x28, 0x8e, 0xc6, 0xf5, 0xe7,
0xc2, 0x97, 0x78, 0x6a, 0xa0, 0xd3, 0x2d, 0x01,
}, 20,
42, {
0x0a, 0xc1, 0xaf, 0x70, 0x02, 0xb3, 0xd7, 0x61, 0xd1, 0xe5, 0x52, 0x98,
0xda, 0x9d, 0x05, 0x06, 0xb9, 0xae, 0x52, 0x05, 0x72, 0x20, 0xa3, 0x06,
@@ -204,6 +233,10 @@ static const hkdf_test_vector_t kTests[] = {
{
0,
}, 0,
{
0x2a, 0xdc, 0xca, 0xda, 0x18, 0x77, 0x9e, 0x7c, 0x20, 0x77, 0xad, 0x2e,
0xb1, 0x9d, 0x3f, 0x3e, 0x73, 0x13, 0x85, 0xdd,
}, 20,
42, {
0x2c, 0x91, 0x11, 0x72, 0x04, 0xd7, 0x45, 0xf3, 0x50, 0x0d, 0x63, 0x6a,
0x62, 0xf6, 0x4f, 0x0a, 0xb3, 0xba, 0xe5, 0x48, 0xaa, 0x53, 0xd4, 0x23,
@@ -214,13 +247,36 @@ static const hkdf_test_vector_t kTests[] = {
};
int main(void) {
uint8_t buf[82];
size_t i;
uint8_t buf[82], prk[EVP_MAX_MD_SIZE];
size_t i, prk_len;
CRYPTO_library_init();
for (i = 0; i < sizeof(kTests) / sizeof(kTests[0]); i++) {
const hkdf_test_vector_t *test = &kTests[i];
if (!HKDF_extract(prk, &prk_len, test->md_func(), test->ikm, test->ikm_len,
test->salt, test->salt_len)) {
fprintf(stderr, "Call to HKDF_extract failed\n");
ERR_print_errors_fp(stderr);
return 1;
}
if (prk_len != test->prk_len ||
memcmp(prk, test->prk, test->prk_len) != 0) {
fprintf(stderr, "%zu: Resulting PRK does not match test vector\n", i);
return 1;
}
if (!HKDF_expand(buf, test->out_len, test->md_func(), prk, prk_len,
test->info, test->info_len)) {
fprintf(stderr, "Call to HKDF_expand failed\n");
ERR_print_errors_fp(stderr);
return 1;
}
if (memcmp(buf, test->out, test->out_len) != 0) {
fprintf(stderr,
"%zu: Resulting key material does not match test vector\n", i);
return 1;
}
if (!HKDF(buf, test->out_len, test->md_func(), test->ikm, test->ikm_len,
test->salt, test->salt_len, test->info, test->info_len)) {
fprintf(stderr, "Call to HKDF failed\n");
@@ -228,9 +284,8 @@ int main(void) {
return 1;
}
if (memcmp(buf, test->out, test->out_len) != 0) {
fprintf(stderr, "%" OPENSSL_PR_SIZE_T
": Resulting key material does not match test vector\n",
i);
fprintf(stderr,
"%zu: Resulting key material does not match test vector\n", i);
return 1;
}
}
+6 -5
View File
@@ -59,6 +59,7 @@
#include <assert.h>
#include <string.h>
#include <openssl/digest.h>
#include <openssl/mem.h>
@@ -115,8 +116,8 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len,
* case. Fix to API to avoid this. */
if (md != ctx->md || key != NULL) {
size_t i;
uint8_t pad[HMAC_MAX_MD_CBLOCK];
uint8_t key_block[HMAC_MAX_MD_CBLOCK];
uint8_t pad[EVP_MAX_MD_BLOCK_SIZE];
uint8_t key_block[EVP_MAX_MD_BLOCK_SIZE];
unsigned key_block_len;
size_t block_size = EVP_MD_block_size(md);
@@ -134,11 +135,11 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len,
key_block_len = (unsigned)key_len;
}
/* Keys are then padded with zeros. */
if (key_block_len != HMAC_MAX_MD_CBLOCK) {
if (key_block_len != EVP_MAX_MD_BLOCK_SIZE) {
memset(&key_block[key_block_len], 0, sizeof(key_block) - key_block_len);
}
for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) {
for (i = 0; i < EVP_MAX_MD_BLOCK_SIZE; i++) {
pad[i] = 0x36 ^ key_block[i];
}
if (!EVP_DigestInit_ex(&ctx->i_ctx, md, impl) ||
@@ -146,7 +147,7 @@ int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len,
return 0;
}
for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) {
for (i = 0; i < EVP_MAX_MD_BLOCK_SIZE; i++) {
pad[i] = 0x5c ^ key_block[i];
}
if (!EVP_DigestInit_ex(&ctx->o_ctx, md, impl) ||
+47 -21
View File
@@ -123,9 +123,9 @@
#if defined(OPENSSL_NO_THREADS)
#elif defined(OPENSSL_WINDOWS)
#pragma warning(push, 3)
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <windows.h>
#pragma warning(pop)
OPENSSL_MSVC_PRAGMA(warning(pop))
#else
#include <pthread.h>
#endif
@@ -152,6 +152,19 @@ typedef __uint128_t uint128_t;
#endif
/* buffers_alias returns one if |a| and |b| alias and zero otherwise. */
static inline int buffers_alias(const uint8_t *a, size_t a_len,
const uint8_t *b, size_t b_len) {
/* Cast |a| and |b| to integers. In C, pointer comparisons between unrelated
* objects are undefined whereas pointer to integer conversions are merely
* implementation-defined. We assume the implementation defined it in a sane
* way. */
uintptr_t a_u = (uintptr_t)a;
uintptr_t b_u = (uintptr_t)b;
return a_u + a_len > b_u && b_u + b_len > a_u;
}
/* Constant-time utility functions.
*
* The following methods return a bitmask of all ones (0xff...f) for true and 0
@@ -294,12 +307,22 @@ static inline int constant_time_select_int(unsigned int mask, int a, int b) {
/* Thread-safe initialisation. */
/* Android's mingw-w64 has some prototypes for INIT_ONCE, but is missing
* others. Work around the missing ones.
*
* TODO(davidben): Remove this once Android's mingw-w64 is upgraded. See
* b/26523949. */
#if defined(__MINGW32__) && !defined(INIT_ONCE_STATIC_INIT)
typedef RTL_RUN_ONCE INIT_ONCE;
#define INIT_ONCE_STATIC_INIT RTL_RUN_ONCE_INIT
#endif
#if defined(OPENSSL_NO_THREADS)
typedef uint32_t CRYPTO_once_t;
#define CRYPTO_ONCE_INIT 0
#elif defined(OPENSSL_WINDOWS)
typedef volatile LONG CRYPTO_once_t;
#define CRYPTO_ONCE_INIT 0
typedef INIT_ONCE CRYPTO_once_t;
#define CRYPTO_ONCE_INIT INIT_ONCE_STATIC_INIT
#else
typedef pthread_once_t CRYPTO_once_t;
#define CRYPTO_ONCE_INIT PTHREAD_ONCE_INIT
@@ -345,22 +368,19 @@ OPENSSL_EXPORT int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *count);
* |CRYPTO_STATIC_MUTEX_INIT|.
*
* |CRYPTO_MUTEX| can appear in public structures and so is defined in
* thread.h.
*
* The global lock is a different type because there's no static initialiser
* value on Windows for locks, so global locks have to be coupled with a
* |CRYPTO_once_t| to ensure that the lock is setup before use. This is done
* automatically by |CRYPTO_STATIC_MUTEX_lock_*|. */
* thread.h as a structure large enough to fit the real type. The global lock is
* a different type so it may be initialized with platform initializer macros.*/
#if defined(OPENSSL_NO_THREADS)
struct CRYPTO_STATIC_MUTEX {};
#define CRYPTO_STATIC_MUTEX_INIT {}
struct CRYPTO_STATIC_MUTEX {
char padding; /* Empty structs have different sizes in C and C++. */
};
#define CRYPTO_STATIC_MUTEX_INIT { 0 }
#elif defined(OPENSSL_WINDOWS)
struct CRYPTO_STATIC_MUTEX {
CRYPTO_once_t once;
CRITICAL_SECTION lock;
SRWLOCK lock;
};
#define CRYPTO_STATIC_MUTEX_INIT { CRYPTO_ONCE_INIT, { 0 } }
#define CRYPTO_STATIC_MUTEX_INIT { SRWLOCK_INIT }
#else
struct CRYPTO_STATIC_MUTEX {
pthread_rwlock_t lock;
@@ -373,16 +393,18 @@ struct CRYPTO_STATIC_MUTEX {
OPENSSL_EXPORT void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock);
/* CRYPTO_MUTEX_lock_read locks |lock| such that other threads may also have a
* read lock, but none may have a write lock. (On Windows, read locks are
* actually fully exclusive.) */
* read lock, but none may have a write lock. */
OPENSSL_EXPORT void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock);
/* CRYPTO_MUTEX_lock_write locks |lock| such that no other thread has any type
* of lock on it. */
OPENSSL_EXPORT void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock);
/* CRYPTO_MUTEX_unlock unlocks |lock|. */
OPENSSL_EXPORT void CRYPTO_MUTEX_unlock(CRYPTO_MUTEX *lock);
/* CRYPTO_MUTEX_unlock_read unlocks |lock| for reading. */
OPENSSL_EXPORT void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock);
/* CRYPTO_MUTEX_unlock_write unlocks |lock| for writing. */
OPENSSL_EXPORT void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock);
/* CRYPTO_MUTEX_cleanup releases all resources held by |lock|. */
OPENSSL_EXPORT void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock);
@@ -401,8 +423,12 @@ OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_lock_read(
OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_lock_write(
struct CRYPTO_STATIC_MUTEX *lock);
/* CRYPTO_STATIC_MUTEX_unlock unlocks |lock|. */
OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_unlock(
/* CRYPTO_STATIC_MUTEX_unlock_read unlocks |lock| for reading. */
OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_unlock_read(
struct CRYPTO_STATIC_MUTEX *lock);
/* CRYPTO_STATIC_MUTEX_unlock_write unlocks |lock| for writing. */
OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_unlock_write(
struct CRYPTO_STATIC_MUTEX *lock);
+4
View File
@@ -152,7 +152,11 @@ int main(int argc, char **argv) {
case 1:
s = rand_string();
lh_insert(lh, (void **)&s1, s);
#if defined(OPENSSL_WINDOWS)
dummy_lh_insert(&dummy_lh, &s2, _strdup(s));
#else
dummy_lh_insert(&dummy_lh, &s2, strdup(s));
#endif
if (s1 != NULL && (s2 == NULL || strcmp(s1, s2) != 0)) {
fprintf(stderr, "lh_insert failure\n");
+15 -6
View File
@@ -66,9 +66,17 @@
#include <string.h>
#if defined(OPENSSL_WINDOWS)
#pragma warning(push, 3)
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <windows.h>
#pragma warning(pop)
/* Work around a clang-cl bug: SecureZeroMemory() below uses __stosb() but
* windows.h only declares that intrinsic and then uses `#pragma intrinsic` for
* it. clang-cl doesn't implement `#pragma intrinsic` yet; it instead defines
* the function as an always-inline symbol in its intrin.h.
* TODO(thakis): Remove this once http://llvm.org/PR19898 is fixed.
*/
#include <intrin.h>
OPENSSL_MSVC_PRAGMA(warning(pop))
#else
#include <strings.h>
#endif
@@ -118,12 +126,11 @@ void OPENSSL_cleanse(void *ptr, size_t len) {
}
int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) {
size_t i;
const uint8_t *a = in_a;
const uint8_t *b = in_b;
uint8_t x = 0;
for (i = 0; i < len; i++) {
for (size_t i = 0; i < len; i++) {
x |= a[i] ^ b[i];
}
@@ -147,8 +154,6 @@ uint32_t OPENSSL_hash32(const void *ptr, size_t len) {
return h;
}
char *OPENSSL_strdup(const char *s) { return strdup(s); }
size_t OPENSSL_strnlen(const char *s, size_t len) {
size_t i;
@@ -163,6 +168,8 @@ size_t OPENSSL_strnlen(const char *s, size_t len) {
#if defined(OPENSSL_WINDOWS)
char *OPENSSL_strdup(const char *s) { return _strdup(s); }
int OPENSSL_strcasecmp(const char *a, const char *b) {
return _stricmp(a, b);
}
@@ -173,6 +180,8 @@ int OPENSSL_strncasecmp(const char *a, const char *b, size_t n) {
#else
char *OPENSSL_strdup(const char *s) { return strdup(s); }
int OPENSSL_strcasecmp(const char *a, const char *b) {
return strcasecmp(a, b);
}
+5 -6
View File
@@ -57,14 +57,13 @@
OPENSSL_COMPILE_ASSERT((16 % sizeof(size_t)) == 0, bad_size_t_size);
void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
const void *key, uint8_t ivec[16], int *num, int enc,
block128_f block) {
unsigned int n;
const void *key, uint8_t ivec[16], unsigned *num,
int enc, block128_f block) {
size_t l = 0;
assert(in && out && key && ivec && num);
n = *num;
unsigned n = *num;
if (enc) {
while (n && len) {
@@ -199,7 +198,7 @@ static void cfbr_encrypt_block(const uint8_t *in, uint8_t *out, unsigned nbits,
/* N.B. This expects the input to be packed, MS bit first */
void CRYPTO_cfb128_1_encrypt(const uint8_t *in, uint8_t *out, size_t bits,
const void *key, uint8_t ivec[16], int *num,
const void *key, uint8_t ivec[16], unsigned *num,
int enc, block128_f block) {
size_t n;
uint8_t c[1], d[1];
@@ -217,7 +216,7 @@ void CRYPTO_cfb128_1_encrypt(const uint8_t *in, uint8_t *out, size_t bits,
void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const void *key,
unsigned char ivec[16], int *num, int enc,
unsigned char ivec[16], unsigned *num, int enc,
block128_f block) {
size_t n;
+1 -3
View File
@@ -282,9 +282,7 @@ static int decode_hex(uint8_t **out, size_t *out_len, const char *in,
uint8_t v, v2;
if (!from_hex(&v, in[i]) ||
!from_hex(&v2, in[i+1])) {
fprintf(stderr,
"%u: invalid hex digit in %s around offset %" OPENSSL_PR_SIZE_T
".\n",
fprintf(stderr, "%u: invalid hex digit in %s around offset %zu.\n",
test_num, description, i);
goto err;
}
+9 -9
View File
@@ -121,9 +121,9 @@ extern "C" {
#endif
#elif defined(_MSC_VER)
#if _MSC_VER >= 1300
#pragma warning(push, 3)
OPENSSL_MSVC_PRAGMA(warning(push, 3))
#include <intrin.h>
#pragma warning(pop)
OPENSSL_MSVC_PRAGMA(warning(pop))
#pragma intrinsic(_byteswap_uint64, _byteswap_ulong)
#define BSWAP8(x) _byteswap_uint64((uint64_t)(x))
#define BSWAP4(x) _byteswap_ulong((uint32_t)(x))
@@ -200,7 +200,7 @@ typedef void (*ctr128_f)(const uint8_t *in, uint8_t *out, size_t blocks,
* incremented by this function. */
void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
const void *key, uint8_t ivec[16],
uint8_t ecount_buf[16], unsigned int *num,
uint8_t ecount_buf[16], unsigned *num,
block128_f block);
/* CRYPTO_ctr128_encrypt_ctr32 acts like |CRYPTO_ctr128_encrypt| but takes
@@ -209,7 +209,7 @@ void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
* function. */
void CRYPTO_ctr128_encrypt_ctr32(const uint8_t *in, uint8_t *out, size_t len,
const void *key, uint8_t ivec[16],
uint8_t ecount_buf[16], unsigned int *num,
uint8_t ecount_buf[16], unsigned *num,
ctr128_f ctr);
@@ -313,7 +313,7 @@ void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len,
* call. */
void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out,
size_t len, const void *key, uint8_t ivec[16],
int *num, block128_f block);
unsigned *num, block128_f block);
/* CFB. */
@@ -323,21 +323,21 @@ void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out,
* |len| be a multiple of any value and any partial blocks are stored in |ivec|
* and |*num|, the latter must be zero before the initial call. */
void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
const void *key, uint8_t ivec[16], int *num, int enc,
block128_f block);
const void *key, uint8_t ivec[16], unsigned *num,
int enc, block128_f block);
/* CRYPTO_cfb128_8_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes
* from |in| to |out| using |block| in CFB-8 mode. Prior to the first call
* |num| should be set to zero. */
void CRYPTO_cfb128_8_encrypt(const uint8_t *in, uint8_t *out, size_t len,
const void *key, uint8_t ivec[16], int *num,
const void *key, uint8_t ivec[16], unsigned *num,
int enc, block128_f block);
/* CRYPTO_cfb128_1_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes
* from |in| to |out| using |block| in CFB-1 mode. Prior to the first call
* |num| should be set to zero. */
void CRYPTO_cfb128_1_encrypt(const uint8_t *in, uint8_t *out, size_t bits,
const void *key, uint8_t ivec[16], int *num,
const void *key, uint8_t ivec[16], unsigned *num,
int enc, block128_f block);
size_t CRYPTO_cts128_encrypt_block(const uint8_t *in, uint8_t *out, size_t len,
+2 -4
View File
@@ -56,13 +56,11 @@
OPENSSL_COMPILE_ASSERT((16 % sizeof(size_t)) == 0, bad_size_t_size);
void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t len,
const void *key, uint8_t ivec[16], int *num,
const void *key, uint8_t ivec[16], unsigned *num,
block128_f block) {
unsigned int n;
assert(in && out && key && ivec && num);
n = *num;
unsigned n = *num;
while (n && len) {
*(out++) = *(in++) ^ ivec[n];
+40
View File
@@ -0,0 +1,40 @@
add_library(
newhope
OBJECT
error_correction.c
newhope.c
ntt.c
poly.c
precomp.c
reduce.c
)
add_executable(
newhope_test
newhope_test.cc
$<TARGET_OBJECTS:test_support>
)
add_executable(
newhope_statistical_test
newhope_statistical_test.cc
$<TARGET_OBJECTS:test_support>
)
add_executable(
newhope_vectors_test
newhope_vectors_test.cc
$<TARGET_OBJECTS:test_support>
)
target_link_libraries(newhope_test crypto)
target_link_libraries(newhope_statistical_test crypto)
target_link_libraries(newhope_vectors_test crypto)
add_dependencies(all_tests newhope_test)
add_dependencies(all_tests newhope_statistical_test)
add_dependencies(all_tests newhope_vectors_test)
+131
View File
@@ -0,0 +1,131 @@
/* Copyright (c) 2016, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <string.h>
#include <openssl/base.h>
#include <openssl/rand.h>
#include "internal.h"
/* See paper for details on the error reconciliation */
static int32_t abs_32(int32_t v) {
int32_t mask = v >> 31;
return (v ^ mask) - mask;
}
static int32_t f(int32_t* v0, int32_t* v1, int32_t x) {
int32_t xit, t, r, b;
/* Next 6 lines compute t = x/PARAM_Q */
b = x * 2730;
t = b >> 25;
b = x - t * 12289;
b = 12288 - b;
b >>= 31;
t -= b;
r = t & 1;
xit = (t >> 1);
*v0 = xit + r; /* v0 = round(x/(2*PARAM_Q)) */
t -= 1;
r = t & 1;
*v1 = (t >> 1) + r;
return abs_32(x - ((*v0) * 2 * PARAM_Q));
}
static int32_t g(int32_t x) {
int32_t t, c, b;
/* Next 6 lines compute t = x/(4*PARAM_Q); */
b = x * 2730;
t = b >> 27;
b = x - t * 49156;
b = 49155 - b;
b >>= 31;
t -= b;
c = t & 1;
t = (t >> 1) + c; /* t = round(x/(8*PARAM_Q)) */
t *= 8 * PARAM_Q;
return abs_32(t - x);
}
static int16_t LDDecode(int32_t xi0, int32_t xi1, int32_t xi2, int32_t xi3) {
int32_t t;
t = g(xi0);
t += g(xi1);
t += g(xi2);
t += g(xi3);
t -= 8 * PARAM_Q;
t >>= 31;
return t & 1;
}
void newhope_helprec(NEWHOPE_POLY* c, const NEWHOPE_POLY* v,
const uint8_t rand[32]) {
int32_t v0[4], v1[4], v_tmp[4], k;
uint8_t rbit;
unsigned i;
for (i = 0; i < 256; i++) {
rbit = (rand[i >> 3] >> (i & 7)) & 1;
k = f(v0 + 0, v1 + 0, 8 * v->coeffs[0 + i] + 4 * rbit);
k += f(v0 + 1, v1 + 1, 8 * v->coeffs[256 + i] + 4 * rbit);
k += f(v0 + 2, v1 + 2, 8 * v->coeffs[512 + i] + 4 * rbit);
k += f(v0 + 3, v1 + 3, 8 * v->coeffs[768 + i] + 4 * rbit);
k = (2 * PARAM_Q - 1 - k) >> 31;
v_tmp[0] = ((~k) & v0[0]) ^ (k & v1[0]);
v_tmp[1] = ((~k) & v0[1]) ^ (k & v1[1]);
v_tmp[2] = ((~k) & v0[2]) ^ (k & v1[2]);
v_tmp[3] = ((~k) & v0[3]) ^ (k & v1[3]);
c->coeffs[0 + i] = (v_tmp[0] - v_tmp[3]) & 3;
c->coeffs[256 + i] = (v_tmp[1] - v_tmp[3]) & 3;
c->coeffs[512 + i] = (v_tmp[2] - v_tmp[3]) & 3;
c->coeffs[768 + i] = (-k + 2 * v_tmp[3]) & 3;
}
}
void newhope_reconcile(uint8_t* key, const NEWHOPE_POLY* v,
const NEWHOPE_POLY* c) {
int i;
int32_t tmp[4];
memset(key, 0, NEWHOPE_KEY_LENGTH);
for (i = 0; i < 256; i++) {
tmp[0] = 16 * PARAM_Q + 8 * (int32_t)v->coeffs[0 + i] -
PARAM_Q * (2 * c->coeffs[0 + i] + c->coeffs[768 + i]);
tmp[1] = 16 * PARAM_Q + 8 * (int32_t)v->coeffs[256 + i] -
PARAM_Q * (2 * c->coeffs[256 + i] + c->coeffs[768 + i]);
tmp[2] = 16 * PARAM_Q + 8 * (int32_t)v->coeffs[512 + i] -
PARAM_Q * (2 * c->coeffs[512 + i] + c->coeffs[768 + i]);
tmp[3] = 16 * PARAM_Q + 8 * (int32_t)v->coeffs[768 + i] -
PARAM_Q * (c->coeffs[768 + i]);
key[i >> 3] |= LDDecode(tmp[0], tmp[1], tmp[2], tmp[3]) << (i & 7);
}
}
+71
View File
@@ -0,0 +1,71 @@
/* Copyright (c) 2016, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#ifndef OPENSSL_HEADER_NEWHOPE_INTERNAL_H
#define OPENSSL_HEADER_NEWHOPE_INTERNAL_H
#include <openssl/newhope.h>
#include <openssl/sha.h>
#include "../internal.h"
/* The number of polynomial coefficients. */
#define PARAM_N 1024
/* The width the noise distribution. */
#define PARAM_K 16
/* Modulus. */
#define PARAM_Q 12289
/* Polynomial coefficients in unpacked form. */
struct newhope_poly_st {
uint16_t coeffs[PARAM_N];
};
/* SEED_LENGTH is the length of the AES-CTR seed used to derive a polynomial. */
#define SEED_LENGTH 32
/* newhope_poly_uniform generates the polynomial |a| using AES-CTR mode with the
* seed
* |seed|. (In the reference implementation this was done with SHAKE-128.) */
void newhope_poly_uniform(NEWHOPE_POLY* a, const uint8_t* seed);
void newhope_helprec(NEWHOPE_POLY* c, const NEWHOPE_POLY* v,
const uint8_t rbits[32]);
/* newhope_reconcile performs the error-reconciliation step using the input |v|
* and
* reconciliation data |c|, writing the resulting key to |key|. */
void newhope_reconcile(uint8_t* key, const NEWHOPE_POLY* v,
const NEWHOPE_POLY* c);
/* newhope_poly_invntt performs the inverse of NTT(r) in-place. */
void newhope_poly_invntt(NEWHOPE_POLY* r);
void newhope_poly_add(NEWHOPE_POLY* r, const NEWHOPE_POLY* a,
const NEWHOPE_POLY* b);
void newhope_poly_pointwise(NEWHOPE_POLY* r, const NEWHOPE_POLY* a,
const NEWHOPE_POLY* b);
uint16_t newhope_montgomery_reduce(uint32_t a);
uint16_t newhope_barrett_reduce(uint16_t a);
void newhope_bitrev_vector(uint16_t* poly);
void newhope_mul_coefficients(uint16_t* poly, const uint16_t* factors);
void newhope_ntt(uint16_t* poly, const uint16_t* omegas);
#endif /* OPENSSL_HEADER_NEWHOPE_INTERNAL_H */
+174
View File
@@ -0,0 +1,174 @@
/* Copyright (c) 2016, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <string.h>
#include <openssl/mem.h>
#include <openssl/rand.h>
#include "internal.h"
NEWHOPE_POLY *NEWHOPE_POLY_new(void) {
return (NEWHOPE_POLY *)OPENSSL_malloc(sizeof(NEWHOPE_POLY));
}
void NEWHOPE_POLY_free(NEWHOPE_POLY *p) { OPENSSL_free(p); }
/* Encodes reconciliation data from |c| into |r|. */
static void encode_rec(const NEWHOPE_POLY *c, uint8_t *r) {
int i;
for (i = 0; i < PARAM_N / 4; i++) {
r[i] = c->coeffs[4 * i] | (c->coeffs[4 * i + 1] << 2) |
(c->coeffs[4 * i + 2] << 4) | (c->coeffs[4 * i + 3] << 6);
}
}
/* Decodes reconciliation data from |r| into |c|. */
static void decode_rec(const uint8_t *r, NEWHOPE_POLY *c) {
int i;
for (i = 0; i < PARAM_N / 4; i++) {
c->coeffs[4 * i + 0] = r[i] & 0x03;
c->coeffs[4 * i + 1] = (r[i] >> 2) & 0x03;
c->coeffs[4 * i + 2] = (r[i] >> 4) & 0x03;
c->coeffs[4 * i + 3] = (r[i] >> 6);
}
}
void NEWHOPE_offer(uint8_t *offermsg, NEWHOPE_POLY *s) {
NEWHOPE_POLY_noise_ntt(s);
/* The first part of the offer message is the seed, which compactly encodes
* a. */
NEWHOPE_POLY a;
uint8_t *seed = &offermsg[NEWHOPE_POLY_LENGTH];
RAND_bytes(seed, SEED_LENGTH);
newhope_poly_uniform(&a, seed);
NEWHOPE_POLY e;
NEWHOPE_POLY_noise_ntt(&e);
/* The second part of the offer message is the polynomial pk = a*s+e */
NEWHOPE_POLY pk;
NEWHOPE_offer_computation(&pk, s, &e, &a);
NEWHOPE_POLY_tobytes(offermsg, &pk);
}
int NEWHOPE_accept(uint8_t key[SHA256_DIGEST_LENGTH],
uint8_t acceptmsg[NEWHOPE_ACCEPTMSG_LENGTH],
const uint8_t offermsg[NEWHOPE_OFFERMSG_LENGTH],
size_t msg_len) {
if (msg_len != NEWHOPE_OFFERMSG_LENGTH) {
return 0;
}
/* Decode the |offermsg|, generating the same |a| as the peer, from the peer's
* seed. */
NEWHOPE_POLY pk, a;
NEWHOPE_offer_frommsg(&pk, &a, offermsg);
/* Generate noise polynomials used to generate our key. */
NEWHOPE_POLY sp, ep, epp;
NEWHOPE_POLY_noise_ntt(&sp);
NEWHOPE_POLY_noise_ntt(&ep);
NEWHOPE_POLY_noise(&epp); /* intentionally not NTT */
/* Generate random bytes used for reconciliation. (The reference
* implementation calls ChaCha20 here.) */
uint8_t rand[32];
RAND_bytes(rand, sizeof(rand));
/* Encode |bp| and |c| as the |acceptmsg|. */
NEWHOPE_POLY bp, c;
uint8_t k[NEWHOPE_KEY_LENGTH];
NEWHOPE_accept_computation(k, &bp, &c, &sp, &ep, &epp, rand, &pk, &a);
NEWHOPE_POLY_tobytes(acceptmsg, &bp);
encode_rec(&c, &acceptmsg[NEWHOPE_POLY_LENGTH]);
SHA256_CTX ctx;
if (!SHA256_Init(&ctx) ||
!SHA256_Update(&ctx, k, NEWHOPE_KEY_LENGTH) ||
!SHA256_Final(key, &ctx)) {
return 0;
}
return 1;
}
int NEWHOPE_finish(uint8_t key[SHA256_DIGEST_LENGTH], const NEWHOPE_POLY *sk,
const uint8_t acceptmsg[NEWHOPE_ACCEPTMSG_LENGTH],
size_t msg_len) {
if (msg_len != NEWHOPE_ACCEPTMSG_LENGTH) {
return 0;
}
/* Decode the accept message into |bp| and |c|. */
NEWHOPE_POLY bp, c;
NEWHOPE_POLY_frombytes(&bp, acceptmsg);
decode_rec(&acceptmsg[NEWHOPE_POLY_LENGTH], &c);
uint8_t k[NEWHOPE_KEY_LENGTH];
NEWHOPE_finish_computation(k, sk, &bp, &c);
SHA256_CTX ctx;
if (!SHA256_Init(&ctx) ||
!SHA256_Update(&ctx, k, NEWHOPE_KEY_LENGTH) ||
!SHA256_Final(key, &ctx)) {
return 0;
}
return 1;
}
void NEWHOPE_offer_computation(NEWHOPE_POLY *out_pk,
const NEWHOPE_POLY *s, const NEWHOPE_POLY *e,
const NEWHOPE_POLY *a) {
NEWHOPE_POLY r;
newhope_poly_pointwise(&r, s, a);
newhope_poly_add(out_pk, e, &r);
}
void NEWHOPE_accept_computation(
uint8_t k[NEWHOPE_KEY_LENGTH], NEWHOPE_POLY *bp,
NEWHOPE_POLY *reconciliation,
const NEWHOPE_POLY *sp, const NEWHOPE_POLY *ep, const NEWHOPE_POLY *epp,
const uint8_t rand[32],
const NEWHOPE_POLY *pk, const NEWHOPE_POLY *a) {
/* bp = a*s' + e' */
newhope_poly_pointwise(bp, a, sp);
newhope_poly_add(bp, bp, ep);
/* v = pk * s' + e'' */
NEWHOPE_POLY v;
newhope_poly_pointwise(&v, pk, sp);
newhope_poly_invntt(&v);
newhope_poly_add(&v, &v, epp);
newhope_helprec(reconciliation, &v, rand);
newhope_reconcile(k, &v, reconciliation);
}
void NEWHOPE_finish_computation(uint8_t k[NEWHOPE_KEY_LENGTH],
const NEWHOPE_POLY *sk, const NEWHOPE_POLY *bp,
const NEWHOPE_POLY *reconciliation) {
NEWHOPE_POLY v;
newhope_poly_pointwise(&v, sk, bp);
newhope_poly_invntt(&v);
newhope_reconcile(k, &v, reconciliation);
}
void NEWHOPE_offer_frommsg(NEWHOPE_POLY *out_pk, NEWHOPE_POLY *out_a,
const uint8_t offermsg[NEWHOPE_OFFERMSG_LENGTH]) {
NEWHOPE_POLY_frombytes(out_pk, offermsg);
const uint8_t *seed = offermsg + NEWHOPE_POLY_LENGTH;
newhope_poly_uniform(out_a, seed);
}
+156
View File
@@ -0,0 +1,156 @@
/* Copyright (c) 2016, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <string>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/rand.h>
#include "../test/scoped_types.h"
#include "internal.h"
static const unsigned kNumTests = 1000;
static bool TestNoise(void) {
printf("noise distribution:\n");
size_t buckets[1 + 2 * PARAM_K];
memset(buckets, 0, sizeof(buckets));
for (size_t i = 0; i < kNumTests; i++) {
NEWHOPE_POLY s;
NEWHOPE_POLY_noise(&s);
for (int j = 0; j < PARAM_N; j++) {
uint16_t value = (s.coeffs[j] + PARAM_K) % PARAM_Q;
buckets[value]++;
}
}
int64_t sum = 0, square_sum = 0;
for (int64_t i = 0; i < 1 + 2 * PARAM_K; i++) {
sum += (i - PARAM_K) * (int64_t) buckets[i];
square_sum += (i - PARAM_K) * (i - PARAM_K) * (int64_t) buckets[i];
}
double mean = double(sum) / double(PARAM_N * kNumTests);
double expected_variance = 0.5 * 0.5 * double(PARAM_K * 2);
double variance = double(square_sum) / double(PARAM_N * kNumTests) - mean * mean;
for (size_t i = 0; i < 1 + 2 * PARAM_K; i++) {
std::string dots;
for (size_t j = 0; j < 79 * buckets[i] / buckets[PARAM_K]; j++) {
dots += "+";
}
printf("%+zd\t%zd\t%s\n", i - PARAM_K, buckets[i], dots.c_str());
}
printf("mean: got %f, want %f\n", mean, 0.0);
printf("variance: got %f, want %f\n", variance, expected_variance);
printf("\n");
if (mean < -0.5 || 0.5 < mean) {
fprintf(stderr, "mean out of range: %f\n", mean);
return false;
}
if (variance < expected_variance - 1.0 || expected_variance + 1.0 < variance) {
fprintf(stderr, "variance out of range: got %f, want %f\n", variance,
expected_variance);
return false;
}
return true;
}
static int Hamming32(const uint8_t key[NEWHOPE_KEY_LENGTH]) {
static int kHamming[256] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8,
};
int r = 0;
for(int i = 0; i < NEWHOPE_KEY_LENGTH; i++) {
r += kHamming[key[i]];
}
return r;
}
static bool TestKeys(void) {
printf("keys (prior to whitening):\n");
uint8_t key[NEWHOPE_KEY_LENGTH];
uint8_t offermsg[NEWHOPE_OFFERMSG_LENGTH];
ScopedNEWHOPE_POLY sk(NEWHOPE_POLY_new()), pk(NEWHOPE_POLY_new()),
sp(NEWHOPE_POLY_new()), ep(NEWHOPE_POLY_new()), epp(NEWHOPE_POLY_new()),
a(NEWHOPE_POLY_new()), bp(NEWHOPE_POLY_new()), rec(NEWHOPE_POLY_new());
int ones = 0;
for (size_t i = 0; i < kNumTests; i++) {
NEWHOPE_offer(offermsg, sk.get());
NEWHOPE_offer_frommsg(pk.get(), a.get(), offermsg);
NEWHOPE_POLY_noise_ntt(sp.get());
NEWHOPE_POLY_noise_ntt(ep.get());
NEWHOPE_POLY_noise(epp.get()); /* intentionally not NTT */
uint8_t rand[32];
RAND_bytes(rand, 32);
NEWHOPE_accept_computation(key, bp.get(), rec.get(),
sp.get(), ep.get(), epp.get(), rand,
pk.get(), a.get());
ones += Hamming32(key);
}
int bits = NEWHOPE_KEY_LENGTH * 8 * kNumTests;
int diff = bits - 2 * ones;
double fraction = (double) abs(diff) / bits;
printf("ones: %d\n", ones);
printf("zeroes: %d\n", (bits - ones));
printf("diff: got %d (%f), want 0\n", diff, fraction);
printf("\n");
if (fraction > 0.01) {
fprintf(stderr, "key bias is too high (%f)\n", fraction);
return false;
}
return true;
}
int main(void) {
if (!TestKeys() ||
!TestNoise()) {
return 1;
}
printf("PASS\n");
return 0;
}
+142
View File
@@ -0,0 +1,142 @@
/* Copyright (c) 2016, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/rand.h>
#include "../test/scoped_types.h"
#include "internal.h"
// Set to 10 for quick execution. Tested up to 1,000,000.
static const int kNumTests = 10;
static bool TestKeys(void) {
// Alice generates a public key.
ScopedNEWHOPE_POLY sk(NEWHOPE_POLY_new());
uint8_t offer_msg[NEWHOPE_OFFERMSG_LENGTH];
NEWHOPE_offer(offer_msg, sk.get());
// Bob derives a secret key and creates a response.
uint8_t accept_msg[NEWHOPE_ACCEPTMSG_LENGTH];
uint8_t accept_key[SHA256_DIGEST_LENGTH];
if (!NEWHOPE_accept(accept_key, accept_msg, offer_msg, sizeof(offer_msg))) {
fprintf(stderr, "ERROR accept key exchange failed\n");
return false;
}
// Alice uses Bob's response to get her secret key.
uint8_t offer_key[SHA256_DIGEST_LENGTH];
if (!NEWHOPE_finish(offer_key, sk.get(), accept_msg, sizeof(accept_msg))) {
fprintf(stderr, "ERROR finish key exchange failed\n");
return false;
}
if (memcmp(offer_key, accept_key, SHA256_DIGEST_LENGTH) != 0) {
fprintf(stderr, "ERROR keys did not agree\n");
return false;
}
return true;
}
static bool TestInvalidSK(void) {
// Alice generates a public key.
uint8_t offer_msg[NEWHOPE_OFFERMSG_LENGTH];
ScopedNEWHOPE_POLY sk(NEWHOPE_POLY_new());
NEWHOPE_offer(offer_msg, sk.get());
// Bob derives a secret key and creates a response.
uint8_t accept_key[SHA256_DIGEST_LENGTH];
uint8_t accept_msg[NEWHOPE_ACCEPTMSG_LENGTH];
if (!NEWHOPE_accept(accept_key, accept_msg, offer_msg, sizeof(offer_msg))) {
fprintf(stderr, "ERROR accept key exchange failed\n");
return false;
}
// Corrupt the secret key. It turns out that you need to corrupt a lot of
// bits to ensure that the key exchange always fails!
sk->coeffs[PARAM_N - 1] = 0;
sk->coeffs[PARAM_N - 2] = 0;
sk->coeffs[PARAM_N - 3] = 0;
sk->coeffs[PARAM_N - 4] = 0;
// Alice uses Bob's response to get her secret key.
uint8_t offer_key[SHA256_DIGEST_LENGTH];
if (!NEWHOPE_finish(offer_key, sk.get(), accept_msg, sizeof(accept_msg))) {
fprintf(stderr, "ERROR finish key exchange failed\n");
return false;
}
if (memcmp(offer_key, accept_key, SHA256_DIGEST_LENGTH) == 0) {
fprintf(stderr, "ERROR keys agreed despite corrupt sk\n");
return false;
}
return true;
}
static bool TestInvalidAcceptMsg(void) {
// Alice generates a public key.
ScopedNEWHOPE_POLY sk(NEWHOPE_POLY_new());
uint8_t offer_msg[NEWHOPE_OFFERMSG_LENGTH];
NEWHOPE_offer(offer_msg, sk.get());
// Bob derives a secret key and creates a response.
uint8_t accept_key[SHA256_DIGEST_LENGTH];
uint8_t accept_msg[NEWHOPE_ACCEPTMSG_LENGTH];
if (!NEWHOPE_accept(accept_key, accept_msg, offer_msg, sizeof(offer_msg))) {
fprintf(stderr, "ERROR accept key exchange failed\n");
return false;
}
// Corrupt the (polynomial part of the) accept message. It turns out that
// you need to corrupt a lot of bits to ensure that the key exchange always
// fails!
accept_msg[PARAM_N - 1] = 0;
accept_msg[PARAM_N - 2] = 0;
accept_msg[PARAM_N - 3] = 0;
accept_msg[PARAM_N - 4] = 0;
// Alice uses Bob's response to get her secret key.
uint8_t offer_key[SHA256_DIGEST_LENGTH];
if (!NEWHOPE_finish(offer_key, sk.get(), accept_msg, sizeof(accept_msg))) {
fprintf(stderr, "ERROR finish key exchange failed\n");
return false;
}
if (!memcmp(offer_key, accept_key, SHA256_DIGEST_LENGTH)) {
fprintf(stderr, "ERROR keys agreed despite corrupt accept message\n");
return false;
}
return true;
}
int main(void) {
for (int i = 0; i < kNumTests; i++) {
if (!TestKeys() ||
!TestInvalidSK() ||
!TestInvalidAcceptMsg()) {
return 1;
}
}
printf("PASS\n");
return 0;
}
+206
View File
@@ -0,0 +1,206 @@
# These vectors were generated by the reference implementation, lightly modified
# to emit the arguments expected by BoringSSL's implementation. Most important,
# this bypasses the random number generation and key whitening steps, which
# differ between the two implementations, and focuses on the common and
# interoperable part.
InRandA = 420c3c6b581c9f4466cd807170629a84b681aa1063a341062aa37956d70ae68befe87727d99fc92e7c29e215c5f13b722587c0d675d79190096a280a192aa4f4e65f982a59130f9266d22e4e8cd9ef195b45813cc8233a253f8a752548529b463226d3ebcf422870739095d567e7f6a512630c6766aa2668e8477a78865849e0b16bd0e4919d1d7da0c5d8005104e6e4d6b6855590e5c6a4e649dc4a0ef5b5ae140251c26b8c32001ed7ad13cda56b94c3294010c84ab54fba1888686384d40e310eb6363b9b23057782805f62e378c27ab98f223324add836772c3e81b8212bdae3c864a59c6e63a72327c42e69711ffcb3b6d04c00293e91d76c50ef9fdf33fd382c769835e0bd4821f65e66797075915f138a6b49051ec406ea750d50384d5d4ce2c9c536d45d3f7a704c6cae8d82f07bc5590f908b308d8c1b8d5e9ee3931d2d55145236f10688ae192f531755b310ccaf3891125af5decb1adbaa85224c47b73c3c8d7fa92ae1635d03d64d73c600486b336c8a511a7e1675a3dec9fcde711601ab73fc4d788d9de3d9f8fe185b87e920550d705f89f3188d1a69f9efc036666d7f5321d71b7eb5436f9bbab400884c08c59bd0a9458fe1e2b7b73d1e2a5ca4b21be5d48125613f0884d15eea9393a4dbb225bb66e5da5d3d98fb20c10761fe0efa5cf00498b29a662df8f8f17a4de3851fa425552aca9544aa89c89981d0f85636f67a862ee4eb844579f5c0f1b9bc0d647b15223aaf0c9edce88815273a0b064772b46dfc933a4dd8db90aa585097b2c6c0564ca90164a43d798403426544bb66637597dcf92a747b7b5ce1f7ba266f5c482d73e8f8b27920a627d1e9154ea745c213988f405ac2a19ec0a37388f8f67cbd9bd7c64222bd14a664eb5146a0645ccb542c21bde65bd2093a9b7622158a9504b0f230276ae1afd7ba6d7267a546e8c08dbdf168be439fe9263427752658d225a2062202ad567235685ab76585b04151f65a63016c9981a635116ab7766789a066d40d122805178f6840ec225e22dc5147d09ed9a53d8582e0e15b25b9a163178314205722adad9e9798c1306adcc002ab59e146302f0e08124945a18bfb10666c6b429124c5f5e61b98e2e8e6defd58b0dd377924f6a8d788c5887c306cf5864931b171936ae80f4911d483ccc804c112a0bc88a80621b0a1a9f8dd9f44f4f84687c54b533b4614d82741fb78006cdd137c422e5441c4513de3ae8a4cf4db9c679fb90c986f97abe8e1060d0392b668de010a0f9f1447445557c2f069f76e285a94f257ed368a70ae2922926c9452c01fa1fad6aac2db43daa67d68b31f3889acd8649a0c7389336d5d6904715984020470493a18fc84aa2bc61e352184714d0f5f46df0e3fa5a3a8a852f981135399d5df8d44b46abd6bfc164c4587e2a79ae255dadd09f964809c57e753105e2575bc987d924f3d7b9bd90747d1b61ce06a56ba60f1813463c418a3ad09821846b6c2b5057aca1939f255acca579b310fc91d112b6669088a66299fb227a7ca15c686604bf47c10d6c4aa1b56d03a7fe23217294866ea820646c372579955ccc16471159b83d8ba016c114c10c961221c28a956fce40806780e043883349d8e8baf8f308610be18c6103a454c8f30cb9465cc9d3be2935e347fc691a503b4c92d311d29abba18497283e646c3ab030a1dcfd295a29bc6517dde0cb295ea89639824c7fa99a968dd7a1aeb1983925258f3d7853517d6b5db4060783b27c949b80989561303d95cea8059e5e7fa520c2d3141fec406d88535d7060b1f4ebbd08cc7687e3d83040c97005d450f4405c557c9e0b71f047ffac98aa6ffea1f5598223163ea918ad5319bb919d9633254156aae2c527521664a6e54abae312e704b0fd335014a66ad8d22bc9862a0d239a9deb2a011553fe38f0100be4705f0a25580ade9b4b24705264326030b06d512f2d4c815ed36827d1078c57882369c1c2129ee1e1f8d51d45ab0d573820f9618fc2a45c25769f99ca51554efa5d086d039655b6a23874e18d02bb3b28a2d43a293b7e0b32d5c5000a222ddb92f945f0bc40a49427d8ab084de1e89cf9c70c9d39e1f902844811bca5775ad2f73ca884314846d474ef957a4d98eb4c98eb94f9cc6b6edd101b78d9a4b5986626752363b3e2c030bc5b0eb49e558d55ebaa92e1627cc166790aba847725bb487d08930714922d764eeae45c2a4157311ae4fdf4995c7781559cd149124a86843682df807d60ee922471be84d830e1cbed3055e281a19b855121977435f057000329a9a0458e51fca4dac4fa36303c02967d7551759b153f653ca653f7016d427ed7bdc6c49896741853148338688a62745e144c2840cb2fd22aabacbd6e7378074da23a68689664d5e804307beeaaef7454101d34c28441ee8456384a752992494ec2c4d4381c3ba3441357d8c545baec472eac58ca0f665992d64e1e1342c639863a09779e88349afa0418f667aebc22b92e7722e956793653992ab5768c170e8e564
InNoiseS = 2e6f8b71cc4ab67f9816984bce92458263794396bd66ec320565045122d1a427408678dc565386f2f993fb14e1422366ade64536811cf943271a185b747eb2d62d13b6d5028b755179d538f915bce3fd7b1e4a2d6d4e6bf29d06554a010502a70a516fd7c6564b323723eb2a8570ceb98603208a349c685ddc1366b55da84b801ec8a5ea3882c6668a394d98b4a1036946ad618f1cf427a9a05676dbc615acb25c53cb83a117964065618b213f1e4851dcf2663638315859704a44b5785bcff0f7fd2a6eff292c2950fc817d5a4b7bccd014d95c4565abf86a6e8cd2b32e9594482e46e505e57932d30ed6639853c74ff2138b122fc46f54c183f11858ebdb2b871ca916109922ea7e3556e63d95028c62d2652c0b9f35af121da795121d5872043711b6a56639e169eb41d9780f6462d140cc7ddeabaed49d9c4e4284d07132d92fc39b98a5c5cd278023e3a1fdfd8875e0a7a2effe4dd3e2897be58520d99c36308caead22987d959a480db2cb76488cf14e4c9bc92887d5107c6df91ab69abd9a11a50a91b41138c22ed8281c58ae49a512c5c203f563bc7950147ded01a7078f8ebeb324e6e305295522df6eb91035ace84be894fa824fe6415b664e1873f3a4ace6f2f5aaad6d121a489688d3c7d307ab2414b79822305f8842339540f42e089df2c1bf0620ec7a306f36b2d4b27c72439875109d6dfbcbc43358f068108555e0f7e2b047140a589cc4be815227c9a29eaf7914e381513e5d9d00fd3296ee894c9641d2b00e79f62f2f62d8b5ade28bdc26fc6e3711c2fe3694ec9c461e28b5524c59fd2a0ff2ff599c04d8b882f23a5ecf917d080130214c262d3826a616f093acfb64fc6c9c82c36708a628c652cbf0ec8911e902caa2e805268b8144e595f1bbfcccbdb8b7a64af5e101fb113e8abec686c1ee7c2a539593b6f80549be9d8b814f360d71d6bbeb569db2e94d52405b8895da9a02495a01ac93ce9847503e107f6b81fa598c539409a7873af606315f82b9eac49b68a6b9f214a84d58083e067edd52d167d1ea65969cb7a40299062a732d2fbfb26139570c97151187741b9d020113651e2ed0cc279893348b2592531a6a1874c317ec638b42339890205705a52099aebb745f2689c54954f32620598048557aafd940650451b5a0e246f683e507d72080ac8b92ea399023f4ca93dbfb54637cd0301171d124d34a48f0db1a2c5f5ae5725271249a1198347b724b22817f649fcc4b02ec374b10b0524e08a9a41771741c2234d6324856c1aad86051d831e62333162aa2a32905d618e76c353a496829e3cc7a07a66b975364907e6da5d983e65004a392b1b8ce692ce1b24030a6756d60f6972a2e8aefef7d761e15645043d7720d1d756d1713b06c16712716f9204e29b2f8a45172b0498328a0d1b8a7a664079123b9851059add99e2209b4911359f42659e24def8cda7bd4da1ae34fa7669f8218d786b8b9ca16520ad54b5553b92cc99541e6f51caec0176729687977979c4726abf5321344edd66f0e03bea512c6dd54b9d6c80f932d4e58e75f8bf97b3e0e15e412704b691334d10541cb7037eb653f084d96afa4c3ab78d2468e4242fbdb24b05db81815280ef458871dbad0c938719a855d80c3392506ac313b755e13e6d587d0e9c11775e8d588cb048f60c64c564024570b474ab83d9a8d2fc7a0eb465803aa2b643a15c59e3f156ad133aca6c9c968d1493d601fa59591c8d0aea49a697a2e7426c36d24f343b292ed2201bb1f2638a2923c8220e0321f081cf465f98b5f69ff3ab78574646e828487f40c6f4d7c28be30391f083e78640a28f7066ab9aac6138a106dc9c3497c38efbcf007062de29a4b7a38397d0305a04b5fca5f51ddf6b026dd9aa1ef88a394aea54f20be3800d488af630522dfbe8306a10f7178ce06c097a3d7ca62b7169365486b4a23c52c1017fd4513268e4a20c5702b8d624d028098bed550389ad8b987c26a0a0bca7478f3c8b5a4c926a2c10c34662de11b7a260539727e75304c0c28b15e7cc6105da18ab6ba720eb6e0bfce3b220f7f68bcbd845ac8c7d166a837c46714721c227b5bd263d2a6fd54c7a7f26267597953943ef22cb9607f65eb829b5e4ae84b1a263c69a77b16827a7dda44bad604831dee420100d2ab45d822cca55378fffc7377d57c381dd92661eb2271599a68f4a5c4811ad16f27c16103ee9e7a802e9011f7fa542f4799d65c448245424c9698fd3d10cde7cbcf6885f6d630e1a7248ca7ab16b6cd8d262e1cc20243d46c5e1c2aa508c22b6aacfa0a4b8c60e2056bc3365c5f3acc45c61b2d12778bdbaac7744423af4b32f52eafd9a7835400ae42d424d8a46c0c03acefe9a684f903f5c8761616cc82e05de264cb7278529f3c3255b8095f64a2f3f5299b3365efb356d856b04731a8c77845336db8c1952a6ee91b64578d620af6052a700989a2338041e767098c996ce97a6f9907c284bd4acd688937617003afb95af11447629d71222919bcd5b4204a
InNoiseE = ec87b3c754016deb580970f1a4368e1befd757ba3720cfb430599d152515761942bd92cad5a6aaefbe10888f6cb7d4112044c2c1e973a9376cab5d17e746ade95e0ae29cceb213494a98e9985409452d91a0794ecbd947039459aed8227cdad69a175666302007ba6f195968c8244c251bc84e8aaf8298654c71b852e253ab286d74d95c934344c85123b44c59ac7772e5baa0b827b197b0b6763016e1765381bb0127f478989c7ab95ad88b5a3c5480a35b16ca8c1fe061727398120c774a8b13307804f06aac48d8b1867265275143d1a126694bf6e5d25b25850e4428593f2cee882b2dc914c7158a6604de4ff643db6a9c286a585710e004b83e63049ef0c902585d55ba708cf292576430b77a86ace85bcd72a95856af4491674a750b438860c7805ea177ac98f1980e98bc1f92a3c4d284e5414689f26d265d23f02322d0a0c8eb60a4f31227e4c5467494a850dc027ea59616135c2db689294ab033201a4298fd02126866a38d814b959bee0a1bd045ca6f47f57a663019196ae7124c357364cc1140213b1a0c9c3651f882f050fb450948710211bb520b3c27d4a078e8bbe4b4c829b1e11199ae5d9ce441ad9c4d456664ca38d15607afcd66b0dc1635e6f0a744c8a0710bba49d00a860a46e3180bed85d8a134a7676ea65d420122e14488d21190092da666a225721213da7cce85ee51ad303e418bdda631d96e94958d749994699bafc6586c652d82e3a2e8d5e9a836606e265ffa5b292db623b8cc3690a90f81d8c59ef1097eb2fe5144d26f3fb30b2253e9d39d708c887665ca2ea9d9415b2aee7adb12794a420c21752a2068bd98ba55276405030684eb3dad424707f7e95b552a8f1aa6696560822f4e4ac551855d4a8d65b334a1174adce5b941a5249ba3e5393fd099cd9dd5589761100ae40c275c344b4d9fd7e95136bb8609f6e458ac04ef59fd22a7d23b6ca3f5b0ede97ee8c1f2c70bee77c213f611a1899d191c302606c61e09d562a3f8e6899398ef3918c259d6950da390aa57e9112652035a03772a422359fe570ce6168374ed3e1ccf299633ba0adde0eec22129bb354fccb7974600ae8232b698492acbe28024671a7f03a0a196bf790ec3d217bb279eb4f6ea041b62d054e19a39658cc671bf15b9d4af6a5a482c49ab18419630afa2b714528ab02326633f70008c8ad77a2a8e4cad9ee226b8ca58f8189508a199129b097d90603536412eec9af1327bc46efac7ffc42894837de833993562616f61cfc8557b5f04b2e5e56ea0e5fb2106e834b70bdd6a1d45a19c020190fd069e950fdd13982994f841f6a4563a470ad65659984dbda7802209dac690ec1d33a099c676d0c0b6866de62b35250683bd363e38804ab077a61944529bb022926c228cbad041f0bbd8de4de790d01dd651ce133d641f45109d3099b82b905fb66aef2111929609e8f4a228262596524be270408c1f7a4d0db3ccc44c78ecbea76fadf63599018f22e99645b07847ee187e71ef72216d52427ac20858efafa1d89cc834bdd8b7f102ca3a08a331f8a2896d148bab795f8d098122d2c640a58221297a536b262bd0e9d4b184d81465ef9b2ae12ab0a71fb2b94bf097db1a2feb7be25de709c1e7e5ceb72c401f0713501cef040c5bccb64146c2cc48b6010496868b10a8fc9ac5438b34ba6970af8cbcf59ae07a72c0a5b0d31663f7212faa22954611abb43380cdb3e8e91ee2194d81efcf20a37b9c5e2f457babe49200772deb96d00857c06d3c8412c844d28654a1a77e2885c044c32581a438df44a1c7f567086687f0fc795fc20e7861b5fe26cb10d2b329ccad97e858e0720233844368ca503a58fc48ac3712bc1c01490c64b37a2f1f9f65a78c983b628568c025c83031e222895bf00decc3d99503887c9080a6269de9ae332a09e2f6be0c8ae34d70ef695b5f17b9f4f6a60443945e6ae69ea4750f65302d9d6a7cee8ae01ba54207645ed0e4e556badf3ac1d82c2a8e0042734c7a275c2a61c00f728eaf90830bcbc5737c22d17842252cfb8570f55ed18eaf5218825a7d81bb00eee79cfe92ee82189712665bfc593ebbb84d420ca07d0594ceb400e75be3774eac5e4925967c5a2e04625f69f5a8a5981dd1173af8a8f42671e73d7684feeec1658f147a09569825e90993bd5cf15491cc06ef6de889dd78bd1d22fcb874843ef6e59766095610d5d247f9be1ab709e621b476923a2647fca9f53da8c78b6d08c179b1be2c2d0a304960922d6ac8e2f61f9c08600bcca591f8de995519ee355a53ba7108f44a6297d2b931d07a96c9c0866c44843f06814b8ae00c5a598f03cd3a5fe5a9f615de8da4f0c4d6d6e2242a62e776033b2061e6af2468fd65a580854afbea8c82c549a0276ee0723bc5233ba4c506b365709b9d15403522ce98de9d3aaf8da8813b7111582b75fab1115d9cedbeba735e3c8de4a7730aac543b0aacf39620a00b686f79b5b48c63a54005c5010b92e980a8e275ac24ab163a14b8acd16a41c7da648f
OutPK = bc8dcdf734ed3f2091a723a0b57fd80c53ba783e9b8f285214dc9805d528f47a6d622c54e160405fcd098ee293f34936927e9e33c7845d33e4d511c4ec8569af4d3af4f3c8165d9262993ef68dc74f2e0a963561320b6c40bbd639526201c952dc5f6e56c3975dccbb6968a566a35629f4867c88700a774dc26025302062db4d391bc4c8adfa270bb609122c45e35dd7cdf25e7b09170891fc0662e5b254731473a4ec5945177d817ad769670a4c6537839e720256b5cd5c8548c3de36d38a543a4f225ee2d526738436afdd80fc6aec16529853a20b1494a1c4589535d89eb9eb9c0008ae519e5d101ef4239c8f78d96746d196568c528bda9d9895b61633cbdc99a44fe794b43b600b4116bd617bb95e935b798a212a305f6e608bdcd09bd725ac7999784f06a05cf156ee93a78ad9c5af0e593be56af5677eb70195f025a87822c443d2a041ad4ae7e37a4a65651a056e3a667c720cd504dfe4ad4d54ba89a5c41e545f13ce34e614bd32029939a2ad98bacb066c71a01a462c45ec9564884649a1671797641895ab0c69d3664e4e42af843d5a7ae8ceb369f2405e6c111f70d7356c57a98086d9996650d0e89a64e003454c5857dc0183cbc4b305a24a5f8c8d8cc8c8b54ee9a2d73a2daa96a9c2eb3ba6298594d5a9ba58a587ce1cc4f34afebcfaee9858112d222106030b5d2923780df294ecd589df9039b2aeac35e640ac90d4b10d1e6b6f903df28898c84f759d3c9830aa6e4934f2a88f5bec4488a6021440271b986d44764825a1c7a62bac0e6812a0f64c10e21a1810ee19f36f931742747ec9997741cbec6def679364c1919307d4361aae1a880706061710417e144a1495f13e372268e2ba017a99d3c9025883445d8f148da36fd55a311e9f8104a974cf993c87029ca7d5ae1fb5cf0d4e6fc985fa6a5839d3d7addacd1c75cc5f903358c01e2c4f72499bfa58646a26e13c152b27e8acf3aa85adfc53b5009459b6b6e6e6311bc9732b823e084708938516d6b9451d4b1799f3a1c2ac60f70cfb8b92c55eb8d81b06bca5a64393a6d7386e1f1e20530310d8ab3f6d0d5bf06a7715ce157a9f622f164d6b1566ba82abaec91be9ac3ebe5a8b75f349600ee12e2685d505548cb66008b8318705c890810e4d04e784c2913c026642344647f8b97ea6ff7a0376b135dd1f9332887316e42da8ed32b42b1a42e4c5b4160457b2d898cd41b5df0ffa970183a59b26272002b2836866d32f696623a768116c2691d1666ac882b974e3cdd0d08e5e7d210db2f5d7349c5b130038e09e0a8fad2db1111d731944b3d6692671490a6af15cc69c1a29863b22e8a6de87239539ce0ceca541e6c4515821af61103ede0e3156ac71d3a29e3a8e4b84f4850b20d193ea55dc073a9d83c846ce3f55dc083ae93612c02f72117a4693a4c023f8e824b5500f61509094a89bab8d531ec8aef5291ac9ebd44cb0a2c9413274007488f32b12f459c5e10b849004902ac03273ce86a7a91a17ab46590ace5b4bd5333d8f5481e4e05fc94b5e68db79e30e6c08dd3c0578ec4fc0c55d6850313c8215b052a22d2f778dace1e33441406d5772a28a7ed892b867dd4c9e2818ff259e115bd4026437cffd7ef65dc4044e9830e64149e34cb695cddde34336b8bb40c00c15bfbdaded1593293a6d166ad39d8336b1178ed121bb13a98ea31a46d9f4817b3d8454e26bf405a32f51c15d1d419112ccd2af006e415bd5e3cfb67aa9d5ec64fc599b026934f7dbba1f4c120558364057a5cc5f901b2c0d411dcbe02342bfe32416277e1937e69a3e87f6ea0f214534f278a022231354653e3537e72b75923be4472a1275cb3cad4cf361dfe6be8c6fec69bd824f2a4d84878acac5e97287805279bdd92f48e8d1342f1a3cd8c711f837be0f188ed54071f9441b2b11b0acbc0c3510b4c4c5beababd27c7176f00c2396a3b81ecd9135e1f0171cd97976415671b28d63cb67996626f088f2de42125989581086dd29e87c6f4ee507537e2c9ac8e0f9827b9454770add19de3c3f8c093e85a93e9aeba6e157e38d8a42cb8893efc9ac78d79b9a02fc0500e4466a2942109de0f351ae313a534db4762802220ec7efd5bdc62ec04810e950dc16dc9f0ccafb6eb4a75db6f412ad3575094e8175290e70688f6780be7388846fc98a394c28ce11f51bc8b1cf54df58f06d4aebe2e185b2b48dd2d39483fe584b56dc1509c26ca5f89aacd27ba102232695a74e0613f91ceba0b385a0c59e60f24fce013b0646ba4d1e38e86a0962b065227b1f2a82e9d594e4125fa7660e7683a9a6d5f8ca7f9fc11f98828ab5f0edf94370e951c5e044190d367e4056ee54b97199d067505258aa5684db9dd24ea1ad52cc8744f5b2683584c131d244311a55985bf09c75d7237ab0607e334d6626278fb21a0150ebaa7ab0b78081bd43c706731ea3ccf9678822ade40320d51c040c9f1072c42562d18c894725ee7105da06e5b694420a639d67f8a1062491620238b0199b1a917b219049
InPK = bc8dcdf734ed3f2091a723a0b57fd80c53ba783e9b8f285214dc9805d528f47a6d622c54e160405fcd098ee293f34936927e9e33c7845d33e4d511c4ec8569af4d3af4f3c8165d9262993ef68dc74f2e0a963561320b6c40bbd639526201c952dc5f6e56c3975dccbb6968a566a35629f4867c88700a774dc26025302062db4d391bc4c8adfa270bb609122c45e35dd7cdf25e7b09170891fc0662e5b254731473a4ec5945177d817ad769670a4c6537839e720256b5cd5c8548c3de36d38a543a4f225ee2d526738436afdd80fc6aec16529853a20b1494a1c4589535d89eb9eb9c0008ae519e5d101ef4239c8f78d96746d196568c528bda9d9895b61633cbdc99a44fe794b43b600b4116bd617bb95e935b798a212a305f6e608bdcd09bd725ac7999784f06a05cf156ee93a78ad9c5af0e593be56af5677eb70195f025a87822c443d2a041ad4ae7e37a4a65651a056e3a667c720cd504dfe4ad4d54ba89a5c41e545f13ce34e614bd32029939a2ad98bacb066c71a01a462c45ec9564884649a1671797641895ab0c69d3664e4e42af843d5a7ae8ceb369f2405e6c111f70d7356c57a98086d9996650d0e89a64e003454c5857dc0183cbc4b305a24a5f8c8d8cc8c8b54ee9a2d73a2daa96a9c2eb3ba6298594d5a9ba58a587ce1cc4f34afebcfaee9858112d222106030b5d2923780df294ecd589df9039b2aeac35e640ac90d4b10d1e6b6f903df28898c84f759d3c9830aa6e4934f2a88f5bec4488a6021440271b986d44764825a1c7a62bac0e6812a0f64c10e21a1810ee19f36f931742747ec9997741cbec6def679364c1919307d4361aae1a880706061710417e144a1495f13e372268e2ba017a99d3c9025883445d8f148da36fd55a311e9f8104a974cf993c87029ca7d5ae1fb5cf0d4e6fc985fa6a5839d3d7addacd1c75cc5f903358c01e2c4f72499bfa58646a26e13c152b27e8acf3aa85adfc53b5009459b6b6e6e6311bc9732b823e084708938516d6b9451d4b1799f3a1c2ac60f70cfb8b92c55eb8d81b06bca5a64393a6d7386e1f1e20530310d8ab3f6d0d5bf06a7715ce157a9f622f164d6b1566ba82abaec91be9ac3ebe5a8b75f349600ee12e2685d505548cb66008b8318705c890810e4d04e784c2913c026642344647f8b97ea6ff7a0376b135dd1f9332887316e42da8ed32b42b1a42e4c5b4160457b2d898cd41b5df0ffa970183a59b26272002b2836866d32f696623a768116c2691d1666ac882b974e3cdd0d08e5e7d210db2f5d7349c5b130038e09e0a8fad2db1111d731944b3d6692671490a6af15cc69c1a29863b22e8a6de87239539ce0ceca541e6c4515821af61103ede0e3156ac71d3a29e3a8e4b84f4850b20d193ea55dc073a9d83c846ce3f55dc083ae93612c02f72117a4693a4c023f8e824b5500f61509094a89bab8d531ec8aef5291ac9ebd44cb0a2c9413274007488f32b12f459c5e10b849004902ac03273ce86a7a91a17ab46590ace5b4bd5333d8f5481e4e05fc94b5e68db79e30e6c08dd3c0578ec4fc0c55d6850313c8215b052a22d2f778dace1e33441406d5772a28a7ed892b867dd4c9e2818ff259e115bd4026437cffd7ef65dc4044e9830e64149e34cb695cddde34336b8bb40c00c15bfbdaded1593293a6d166ad39d8336b1178ed121bb13a98ea31a46d9f4817b3d8454e26bf405a32f51c15d1d419112ccd2af006e415bd5e3cfb67aa9d5ec64fc599b026934f7dbba1f4c120558364057a5cc5f901b2c0d411dcbe02342bfe32416277e1937e69a3e87f6ea0f214534f278a022231354653e3537e72b75923be4472a1275cb3cad4cf361dfe6be8c6fec69bd824f2a4d84878acac5e97287805279bdd92f48e8d1342f1a3cd8c711f837be0f188ed54071f9441b2b11b0acbc0c3510b4c4c5beababd27c7176f00c2396a3b81ecd9135e1f0171cd97976415671b28d63cb67996626f088f2de42125989581086dd29e87c6f4ee507537e2c9ac8e0f9827b9454770add19de3c3f8c093e85a93e9aeba6e157e38d8a42cb8893efc9ac78d79b9a02fc0500e4466a2942109de0f351ae313a534db4762802220ec7efd5bdc62ec04810e950dc16dc9f0ccafb6eb4a75db6f412ad3575094e8175290e70688f6780be7388846fc98a394c28ce11f51bc8b1cf54df58f06d4aebe2e185b2b48dd2d39483fe584b56dc1509c26ca5f89aacd27ba102232695a74e0613f91ceba0b385a0c59e60f24fce013b0646ba4d1e38e86a0962b065227b1f2a82e9d594e4125fa7660e7683a9a6d5f8ca7f9fc11f98828ab5f0edf94370e951c5e044190d367e4056ee54b97199d067505258aa5684db9dd24ea1ad52cc8744f5b2683584c131d244311a55985bf09c75d7237ab0607e334d6626278fb21a0150ebaa7ab0b78081bd43c706731ea3ccf9678822ade40320d51c040c9f1072c42562d18c894725ee7105da06e5b694420a639d67f8a1062491620238b0199b1a917b219049
InA = 420c3c6b581c9f4466cd807170629a84b681aa1063a341062aa37956d70ae68befe87727d99fc92e7c29e215c5f13b722587c0d675d79190096a280a192aa4f4e65f982a59130f9266d22e4e8cd9ef195b45813cc8233a253f8a752548529b463226d3ebcf422870739095d567e7f6a512630c6766aa2668e8477a78865849e0b16bd0e4919d1d7da0c5d8005104e6e4d6b6855590e5c6a4e649dc4a0ef5b5ae140251c26b8c32001ed7ad13cda56b94c3294010c84ab54fba1888686384d40e310eb6363b9b23057782805f62e378c27ab98f223324add836772c3e81b8212bdae3c864a59c6e63a72327c42e69711ffcb3b6d04c00293e91d76c50ef9fdf33fd382c769835e0bd4821f65e66797075915f138a6b49051ec406ea750d50384d5d4ce2c9c536d45d3f7a704c6cae8d82f07bc5590f908b308d8c1b8d5e9ee3931d2d55145236f10688ae192f531755b310ccaf3891125af5decb1adbaa85224c47b73c3c8d7fa92ae1635d03d64d73c600486b336c8a511a7e1675a3dec9fcde711601ab73fc4d788d9de3d9f8fe185b87e920550d705f89f3188d1a69f9efc036666d7f5321d71b7eb5436f9bbab400884c08c59bd0a9458fe1e2b7b73d1e2a5ca4b21be5d48125613f0884d15eea9393a4dbb225bb66e5da5d3d98fb20c10761fe0efa5cf00498b29a662df8f8f17a4de3851fa425552aca9544aa89c89981d0f85636f67a862ee4eb844579f5c0f1b9bc0d647b15223aaf0c9edce88815273a0b064772b46dfc933a4dd8db90aa585097b2c6c0564ca90164a43d798403426544bb66637597dcf92a747b7b5ce1f7ba266f5c482d73e8f8b27920a627d1e9154ea745c213988f405ac2a19ec0a37388f8f67cbd9bd7c64222bd14a664eb5146a0645ccb542c21bde65bd2093a9b7622158a9504b0f230276ae1afd7ba6d7267a546e8c08dbdf168be439fe9263427752658d225a2062202ad567235685ab76585b04151f65a63016c9981a635116ab7766789a066d40d122805178f6840ec225e22dc5147d09ed9a53d8582e0e15b25b9a163178314205722adad9e9798c1306adcc002ab59e146302f0e08124945a18bfb10666c6b429124c5f5e61b98e2e8e6defd58b0dd377924f6a8d788c5887c306cf5864931b171936ae80f4911d483ccc804c112a0bc88a80621b0a1a9f8dd9f44f4f84687c54b533b4614d82741fb78006cdd137c422e5441c4513de3ae8a4cf4db9c679fb90c986f97abe8e1060d0392b668de010a0f9f1447445557c2f069f76e285a94f257ed368a70ae2922926c9452c01fa1fad6aac2db43daa67d68b31f3889acd8649a0c7389336d5d6904715984020470493a18fc84aa2bc61e352184714d0f5f46df0e3fa5a3a8a852f981135399d5df8d44b46abd6bfc164c4587e2a79ae255dadd09f964809c57e753105e2575bc987d924f3d7b9bd90747d1b61ce06a56ba60f1813463c418a3ad09821846b6c2b5057aca1939f255acca579b310fc91d112b6669088a66299fb227a7ca15c686604bf47c10d6c4aa1b56d03a7fe23217294866ea820646c372579955ccc16471159b83d8ba016c114c10c961221c28a956fce40806780e043883349d8e8baf8f308610be18c6103a454c8f30cb9465cc9d3be2935e347fc691a503b4c92d311d29abba18497283e646c3ab030a1dcfd295a29bc6517dde0cb295ea89639824c7fa99a968dd7a1aeb1983925258f3d7853517d6b5db4060783b27c949b80989561303d95cea8059e5e7fa520c2d3141fec406d88535d7060b1f4ebbd08cc7687e3d83040c97005d450f4405c557c9e0b71f047ffac98aa6ffea1f5598223163ea918ad5319bb919d9633254156aae2c527521664a6e54abae312e704b0fd335014a66ad8d22bc9862a0d239a9deb2a011553fe38f0100be4705f0a25580ade9b4b24705264326030b06d512f2d4c815ed36827d1078c57882369c1c2129ee1e1f8d51d45ab0d573820f9618fc2a45c25769f99ca51554efa5d086d039655b6a23874e18d02bb3b28a2d43a293b7e0b32d5c5000a222ddb92f945f0bc40a49427d8ab084de1e89cf9c70c9d39e1f902844811bca5775ad2f73ca884314846d474ef957a4d98eb4c98eb94f9cc6b6edd101b78d9a4b5986626752363b3e2c030bc5b0eb49e558d55ebaa92e1627cc166790aba847725bb487d08930714922d764eeae45c2a4157311ae4fdf4995c7781559cd149124a86843682df807d60ee922471be84d830e1cbed3055e281a19b855121977435f057000329a9a0458e51fca4dac4fa36303c02967d7551759b153f653ca653f7016d427ed7bdc6c49896741853148338688a62745e144c2840cb2fd22aabacbd6e7378074da23a68689664d5e804307beeaaef7454101d34c28441ee8456384a752992494ec2c4d4381c3ba3441357d8c545baec472eac58ca0f665992d64e1e1342c639863a09779e88349afa0418f667aebc22b92e7722e956793653992ab5768c170e8e564
InNoiseSP = b1e6653ab5f2447f5ca626e751a87a4b61dbcc0637a84ff2a9eb2d26e99d642bb6d18b0f0c7f4b29a2a671a88f3723ec76fce25f3ac5c681d1de5909d68ca63991af658c4d1e6ea18df2e97675e4840fc5667c353d8d11a92f6da0aad1e4a104066bb3c82ea9fca43d9c837741010924e5cfc3a235045edf4bf2a5187861fa974dbaca44873e93f9b498f2129111978a7d841e1da8362110c1ba1cd9467b7e664d6485b63a0fa2555e51bbc126b811f19dca151df2bbe8675e992bfc4dac16c207044234120c36b94fbe9fccccd2d6ac293497260de16d0843d2679201520208705b9f1be4debb05893b4622bd9a56c0922bb72508b7ee4278f6410300ae47bba8b086c54a6fcb0202563b42ce667ce869cfa00e3041dc09f08d1a926cad88f5d88037081a2c98053aab975868fa5e4c3ba6febc2f469462ef95a05a8ea492c24615fb4b20699c187718065ae3a6ce3fe3ddcdf257661093d8a712a91aaefe6b17083dacb09011f580b23e6c05cf56457195aa2465bd32769c86d19146062a7a26a756233a301e3e31ccf33268003871e44549df44ba2f025f5a95f8356185e6935df047f3e05f585e515531653255770402ee467e696ec5992a24be84aa5dbffc081c118d865a03016eb2abe0b3ae9413e51971503f1ce58b88f194c1ac7378b7c62a48155c18355d4ea50f4d49a8756399a17717d68a76592d7c02024c7cdd13075b61b98d6055fc64990d36de2769e220b902544fff89bd3a6fcc930be2975c36c25dfe4a38243c95209b2784010a8ea5ae3af906058c563f51ca99b892d523f4a4fa79942a38539b6656d95582901cccb28d63ee45c4c13ef9c22429bd1c1727cd7b203f1936fcefe8d9da9016c58c8ba916e5624d2bb151249527a31f9a866cd278bce94791cfb1263fcd3a15e03a1e50420b157e0478818ae5968d06746ac14352740e258715f1a7a54c5d9849f61204bdb50d55ea545df435fa6efa575e2157b7eb5df2305512c4a91112422824c50411b1b4c5a670e9bb848c395f6d09215b30d954280a0ea720706f8bcc6ed6983ebcf95650d1ed163e3505693abb788879047fb088eabb80e99443120d6a2f166c136bda3e825292c815a668dfd74ea013e62da1a8e036c2c077b11a591a9ec195d3c02258fa817a5ee1d94b0fc4be254387069784b7358f0888dbba567a1db5372c24a7d66a315be8f16f65a46a08986191668b2249ad6d3d87240c4047d59f648a790a7536b9e145c95997058db3679ce3a3691b8f528c36f8269686835deaf32a080dc45fd8fbc1a260998fe9c58c832d52923649954efe60f2d059bc119e07b41917a60eb2a7ad1b84cc9c8a5df830f4a16bc7abad4ab0d5246c9fc2c2d0cd120657d25a3ace31e653aed39b822ea9cc37e6d67c2168c64cb63ade7016ee4a1679c25d1a947901bf4100dc6d1eb69ef88ba9cfd309a385af4baefbc8bb48861199bc810390446367b127921e7f70071cb36775a054d327d71b9d9879e82d1721a686118faf08b400316514d9008248b6375245464d89a6fd8be7725ee1bc6e51963a1a20181ad6eb54a76c019e2fe0c9a981381818d2f6de38011a2bdf2b7391b19ee37f1485e1715a17a3b9b65843470aa3d766f0b4b48a0a566ee8962fcd46c2dfbca77e003b5bccc45a53d874633e899363d497741282a33b66cd01bc306b310d442968121914d9c715f00c1809cc84460fb23c00a9c4b6cc6806cbe3198a9721bfb4d10f14572aa9406023abe1f2282d2cf6c1791a88810b5f8568b123e84144b6aab07657c1d57a473d53e54dccd32aeea0210e7f50ee098dd797b079eddd236ad0675698949f50ce5899dda92611df2b0002e043eba7f05a447e20f2d673c5d0e29b758ebf7959b168e1cb0ad218fe80861a4eb1c665aa7618c09014e893cac6d9487d0d5c8a090035f8c549a80af46158f90de1891579d50839384c4b3bdb66263463c7ca03257acbdfe5a233b98db00c412371bc32788bb9b536f27dc24c2e328f85287acbe2d28add4f4e4908b177b54e994521e53001b63dad66f82ca476612a47f690c09d1109cac06f510d684132c8764e88b0ea5525509472cc27d696412c2172996af3495285ebcbf0499396211d9a1183910262c267d020cf70a09097df20cc41a4d79acb536051b65ad12122e2586028547a6bc2420e97d6f4b6123c42229fec6775bd6fb6c51140bff9b2d19388a5554aa83316556109a544eb67e403a9d59a3619fafbce218b3e47d73829c65a196c87d66ba16079151887d9667abe006646ff1ea7b65ddb2ba39d7a6899fe82b6e8112509ea09fab937be208e6015029143688513836cb1016a12572348b997ac4a52384c60b05933e91650697203106467088d451e145ba368bdda6808d36f7d99120fb349300d949bcd8a18c5001eab4488dbc6ce5beb47733609429e9c895e749141238d044fe08a0d1b662b9e767a65a53767e6924d2d1a88eaab2b6e902309036a6b87bc0a7d9d1e81f8d56b9fac7361e2b837
InNoiseEP = ec67edf27a627e3d6101bbf3f07462e567d1fb24819f549b56922c94641e03c5a90a9e4ded6385f1dea354a97571acc95144eccf6341f42cb8001ddbd2152e5fe9375b6cc01ff0a8ee6545dd1ebe834c6bd860565da3ff58bbdc4ad502de4b7f795ac8de9236822cafe0819d9a7a721c845a9133aff25ef3e75789927214aa0ce6b52591a0f1a104c5da1ebc4e96a65a5d00b4b65365a2e586519f641d17aae4041cea14573b448bda8688588f8495daeb90e1b704a6786ecfb4968682782947bae6847868ace2e111396fc3da551160d56ea6545ab825aaa53a282c2166842b710fbe331a65438b139d9b79815d6660081091f565d1cd65944b9d99429a9198aa2874818b86fb0bd07e16ee14980d79215d958a4ba4385a130c14f8871090deacfb4aa43a9242a09fa8549c19ef5b7139132c62d05128904d0e96e80e54c54a8627bb1b36e6aeb507fc49a8e98671727bc9bb932a7e0bc39e7e81e69e48f596cba6fc4984501a2d49a5be0309d8e434584669af04230797ec7aff98425b4f6a78f78c8455f97273b95e4f97681c11e35ffa533f887cebd95406887a4d78e9594694622d828ffa58516e986ae41f06b004adcaa4db09cf1e3829943859b50d6f5386e31643f210e3ab017b6c3d3de2699aa1a5c47e01907284ff5a194c2f0a743a6888041217e6d2c4584f6050f6665da7782a4a63bc580d1d421248f18940526d45c59e143c835e44e83c6a41b806840725ad43b208496a9ab14667598c97006c00ce0f8a71ad51051840f4c5a2b5ac240af17671d806181b9a6a831a209c52a4b1df3d7f591abd87e6ba422ba8fc77393ea2eb5ed786b6eea749e084dbee8519b5846530da1d0054d683591fda950c99de294471855c0bc774801a2debe19de54ae6a9da175d92fa809152e41ed5d521b57fd1e79a9cb8bb1ee678b4d204524ed97e093f3da40399a24ab468392403769947693182181c0b0c467f0329d7517292240c4a5616db815cdc82f929140d0a511b19407a22a7c2a1caa9783c5985d5947a6bfa5241631182eff0164b9f14602d7a13925146913f70083109e7b4582914821e532841e539ce5e826ad0683b62ee2ca51bca3cc88f1f27c5be927220c0c3495e7bd958ff10effe94d59fe1fadc5a5923e1301b1f4a125fabd6c4dcc4618ddfbf7b5f0ab37d9769a029c90f738a4c949b082a2f6276aa911a1a21cda9c2a2806c35abea606faab2b189420a7b3c48806d2393c9fe67176681490b4a9e340aa68b4dd4aafadd01c4d88c360019aa90ce59612cc30f6004da46ed40acd4a53aa1369687799f150516dee99820044e2a87683b12454afbab7a649498796f00d23314b062bae57a995ab27eafde22e3a4a240be4560821bb64551279b62f326a62adf55d8da21644b68dc93a8a5ab21e10304de99a17c666c1ae81a18d927ecdb9708b3c1dbf9ca21e55af3c3aab449ec089fd672fa3c3d38b82f8186ddf17ec5944c21de687ecae803c7a32a1c5f1546f6387eb32d1c75d006cd6e8b9c6d399c402c6c65e9e512628272e930a4c240989f0bb7fadad62dd4a9e4a4b9ca0c106a1cd8e7842ac8c0dc2a26f6b3f96b484861be2f0981cbf07b6a9598601285885924506d0b8b693a0f590b12a71de0674c2ebb85a094806c57b338b026253b881a34b5915f22d62ca0f231732a851c51295a66f6453865de154323960bc66f7e60c79a2615db49a2b7ad80647e007a909b129750581c1ba4eff7e79675311d3b0961ca335c9a9e54b59911894cef01bace82a6259643c3725d5f6eafc7de7225324e14035adc9f43dc586334dc1c1952ca861939a6f8cdb1f47f321d9be91372989d50b79dce772741870b8fbd1140f812a342b1606b6921bb8d3986d816197e1959c156318ca2c0eda96ba84f7cd2df147a2d3eee5472c548b066665b3a173e2c33970df3c3e25e043542585206f4250ec54978c398731983736165da2628c6d19a035a0e6e8e6147a59055ded74c146655309a28dce3b6cc5c1a6d18c52be99f74abe2f5534832451494647b4e2ed9931fc2fc2d530101ef97d92670cfd5d1d9b95412595a9e6871202e70ada42698aa52b181beb5fe260306271c8b6c5eaa3f257f5080f5866159f9b2470c0a83eda50745d02be4016414979a80be53da68a172882003b788b28a6abf4d1de8c850325f25c309e12c27d2a1464bfcac812e61960130bdbae3907904b6ba3d1ee35b7734428e3a86f6b1b6a079896622c171b29a87a899e12dc929dce6d669630276dba5ebe4636e36e940ea65fc7a2978e4f6d4660c532608f6707c81b15ae7c9787948ad1c6481e978100208497c19d69924e741393722b1880ddd94c2eb75b65b2fce25d63451eb1f0068debd8fa25383462f4295b3ee17b094693dca876e75091a019368388175f025594c8fd2f8a81244868f4229926fb2d4992519eca660accb71739dab701052929c8c375ad8f8763d58611ad8b4e394422d1aadc88055c43decce2a907fc8bdde6b5a5759bd9a
InNoiseEPP = fbafff0b0003000180fffbff0a00038000b0ffeebffd2f0130000800fe2f00100000c00100000000030000b0002000ecbf03c0fffbfff2bf0240fefbffeebf040000f0fff6bf0180ffdbff060006c0000000fcbffe2f0000000300ffafff4b000000ff2f015000fcbf0600003c0008000600002000fcbf01c0ff0b000700007000f0ff06000340ff6b0008000440ff0b000400008000f0ff0a00014000000000c00200000c001400fc2f000c00fbbffeafff1b00fcbf0440ff1b000c000140002000fcbffe2f00bcff0a00fc2fff0b000300ffefff0b0004000180ff2b00f8bf0100003c000800ffefff1b000400000000ecff0e0000b0002000100001000000000c000070fffbff06000300007000f8bf0070010000fbbf00b0000000fcbf00f0ff0b00070006c001200000c00280002000000000f000100004000030001c000800ffefff3b001000f92f00c0fff6bf044000f0ff120005c0ff5b00f4bf0300001c0000000080fffbff020002c0fffbff06000400010000f0bfff6f000000fcbf0000020000f8bf007000f0ff0e0000c0ff0b000400004000c0fffebf01c0ff0b00f4bf007000000003c005c000100004000000000000140000c0004000f4bf0500004c00180005c00040000000020000300000c00180ff0b00fcbf04800100001c0000400000000b0000c0ff1b00ecbf003001300010000030004c00000003800010000400028000f0ff0e000140ff9bff06000540fedbff02c00380001000f8bffe6f00a0ff02c00080ff0b00fbbfff6f004000f0bf0040ffebfffabf01c0fffbff12000040ffdbff0200000000000000c0003000d0fffebf05c0ff0b000b000030ffdbfff2bf028000f0ff0e0003400020000c00ff2f00ccff120000f0ffdbff06000100ff5b0000c001000000000400fe2f00000014000180ff4b00fcbf00b0fffbff0200020001200000c0fbaf00c0ff0a00030000fcff020000c0ff0b001b00fcef000000040000c0ffdbff06000380fffbfffebf000000fcff0e0000b0000000f0bf01c00050000400fd2fff0b000f00040000f0ff02000100011000080002c000300000000200000c0000c0ff2fff0b000f0008c0000000100007c0ff0b00f7bffdef008000f4bf0280ff3b000400feefff0b000800ff2f013000180000b0ff0b000f0001c0001000000000b0ff2b00100002000120000800003000ecff060000c0ffebfffabf02400000000c0000c000000003c0fe2f00f0fff6bf00000000000b000280fffbff02c00030fffbff020002c0ff0b00f7bf0200ffbbff060000b0ff0b00f7bffe6fffdbff02c0faaf0000000c0004c000100010000080ffebfffebf003000ecfffabf05c0fefbff1e00f96f00500004000080ff2b000400010001000003c0038001e0ff1200ffef00c0fffebf0100ff2b00f4bffd6f00d0ff02c000000000000400030000e0ff020007c0ff0b000000fe2f01200000c0fd6f00e0fff6bf0070004000040001400020000c000100002c00f0bf03400030000800038000e0ff020000f0ff0b00fcbf000000ecff02c0ffafff4b0004000140ff6b00f4bf00800020000800000000fcfff6bf02800020000400020000f0ff02c0048000300008000070ff2b000400020000c0fffebffd2f00e0ff0e0000f0ffcbff02c00240000000040002c0ff3b0000000100003c00fcbfff2f000c00f8bf0600004c00080000f00000000800004000e0ffeebfffafff1b000000fe2f004000080002c000c0ff0600fd2f0180000000fd6f002000080000c0ff6b000400040000ccff1200ffef00f0ff02000140002000000002000100000b0000700010000000ff2f00ecff0200fd6f00f0ff0200003001000003c0000001100010000140ff5b00040002c0ff0b000b00ff2f0000000f00ff2f002c00f4bfff2f004000fcbf018000000000000500000c000000034001000018000480fffbfffabf007001e0fffebf050000e0ff0a00000000c0ff1600ff2f002c000400024000f0fffebf0030fffbfff6bf03800010000c0000c0ff1b0000000300001c0000c00280fffbff0600014000000003c0fdafff3b000400fb2f00f0ff020000c0ffdbfff2bf00300010000400060000fcfffebf004000300004000080ff0b00efbf02c00120000400ffafff5b0000c0044000e0ff1a00008001e0ff0e00034000f0ff0a0000b0ff0b00f7bf018000000003000340004000fcbf0030000c0000c0038000d0ff0600fe2f0100000b00feaf004000f8bf0100001000000008c000f0ff0e00000000c0fffebf0280fffbff12000080ffdbff06000380ff4b00f4bf0100000c00f0bf04000200001000ffaf000000f8bf030000fcff02c0007000d0fffebf0380000000fcbfffafff7b000c00028000000004000200002c00fcbfffef002000fcbf02400030000c00fd2f00fcff0a00030000e0ff0a0003c0ffabffeebf0240000000f3bffd2f00ecff16000140ffbbff0a00010001f0ff0600ffefff2b001000
InRand = 51c3483b5f31a30d7cc8457959f83f0d3848d0d82a9af0371d9e54519ccc6e45
OutPK = ac839551f2d26b42e6bab93668afac931834e5d0230e84f450cb25ae52a0e32850da5f44d42cda563e95a64f0e18636a43c50e0d79a7d69a15c5a43a9d2d8db99bd0a43d3d60cecd0ae499aa5c2280daa1ca09b927a8e84abd068e684d0f025d606f60632d85f70e7301444d1495351d018c690aa2ac9e8da8d598dafc87d4921adb9eec3818d91e981da53a9be7fb9053f5a0b107225bff688e01eb1dd0245d30fb2680b2baad0e81495bd21a0d5cf24b96b830b12971a0478902bd6277104e3b11e138b523e5d9d8d6bb4d099c66e92693371558b2ee3222f58db087a1ba2953c8a147b8b21714ece87242d47523c004071306b6eb14358be901b0a88d9e12ccc682d204533a2fe87b578b449bd88a6af1a1c0787a8914dc85ee81ae6cbd53a0f0cbbb3d7aa8965bd7c34c6507d3709211129d802c2eab3e3e1a589948130665b4ff9cb9a050701a0aa3dc62b4999b29a4b604205c0f995d27411260bd93abc5d2566a4b9141c75ba03e28e3223ed9a661bfa9589826a10d525b5332b59f6163ce559ac3cb9cb0352b55d633d5517885c0bb9ea5aeef9f0a586fc0a171ae5b5bf7f6576caa6067b76ab5682a8260d0be3c80219ec7746a9accc6ad47d2994615cae6590214b29f230cb881ec7d59c29be2c5380e3c15ef34a3543dc751e2182a4e397c6d02b0df746741cebc41e6d59f045e8a71086140c212aae224d53eda4812d3ee2c120ceaf7d82814a163dd23682f6902320372e3dacd1cdd4b2d835d493300ec572944d44ee0892d712c144c4706ac47a5307abc08f9f0fd905a6b26af28c050232fe707e08c8217774612e9d5e9206697b8612bf2bff7d50282683ca6d3ecb088bd3eb917e37e4a449a294c6bfa5b6519a0dca0101872c10efed1d9607b102cdacdd893c72e804a96781ad08c89966fb07591696a389948363450bbda9b903aec4d47be629143d7ba1b2f260b88dcd182d345aec4a928766c5bd89b35980fcddae4b80f322e9d2b87d0dd9539330d82c930b15e0bd9b05a73fe6426e9da685b540e3c1d35448aa4a0119bfa30c6326877abf850ed1822ae000132b1501a69865329c74a2b03eea490f6fd1891214d73ba6a4ca5e0db87c70c63a619f7075d348969eb46bb9f5d34926df75586fa49f3cc3975053eba33107a714d627075883bc44f6267ce16971ac5f0ad3c481f421afc9c1a12aef556392d2497ef884abc7a8b8fde85229d42896abbe913b23ec32a136ae3117fdbeca943f91db8c5c41d0037e8a7bf42eba1df45295ed7cc876cda4b07e25106f97435614200e2a74c5781987770c2d0157e558cb64c20029d6774853e2c5da3da0a0973d4bd53e35f96c171002e4312fa6c518fc909690b8fd06436e5b8da9dc297c8cdb7146daa29ad15eefb0f2168b8a3a6c7243a8714106d35adaa29206ad2509ee61f082c5739385d9fcb0b2ab0f5fc8dab55dc670484871c69fcd361987ff1cb6797ae3e51d9974ca6b5087f9a229519e9008ccbef4ab6daa24fcae95be3c4a1167b5e1c460da56b642362e7ed8c7eba8100d793e52bab2082b40e3d8340905dd4dbf660119081160739b281cd16f7a8bd020f69e06aa79505870771fa4219008b9d1ca1b0bd28afe029f299e037dd82c0aa17781009591ce628242f74a0ba1526c100e26caba892868da9680b07904545aeda84154384886a4d55118e7948fa2cdaa586f29c25e4fa317ecd3a995c793921106a7d8dc3b2fe3432214bb339614a579661dbbbf07104afa6ad0201ad4b6fd80e90427e6102eb1c02c4d62fbc25464760b6368da0fcb26cb5903eadf6d284328d9867ce610a026d65c1f80a4c7482799e1d3827f945dc6f4a49d6e6667ac5ade72d8804a81830d49c85bd9c431d38372a90198463d2f17a10f1961aa01d0495bf6e8c098248ae5d0740d7c7b266481438e49bf44edf5f9ef345920339a60495c70613aa2ce2988ca67e66572267dcb1aeeaa6146a2a6e69bbe60243fbe2141a6ff802bd581a4d8b351558608ad1db2f0a818c7fea8b49d3e3b17779ce6b5a84a100f368826b15462f0b9f466a947171ac8c0f214f5e25d2c9fe3374e4b121c82d26b45a6fd122662880966b07ca3ea54d1a6c98ae4071866a2c028bd745fd5c91eec2164bb00c1d19131769d196b8f513cec2dbdc562ca2d82261860115d693e232ada6f8446c073e4c1529d34479a5640c648b0b74d1da3a480941ea584d42608bb8e7ddceaed49a9d81d30654866abb70e1924db0c615932f463b749253a4981050ea498ada4edd6728a44538f7982e1b6927d637da0ebb593aa5fa1813c7834027309d1212c7fa29f7204d1da46de261250ad8c0bb725f46742c14f0881d88702fa43efa706406e7c5082bd82a03c92240a01c115a6faef5830ab109491aeadb01ec562b67fc5ac3c529a9db48369788369013d4d298ac375ed33e44371a31b21585c7112c85aae85ea7206c28ee48a7c253561efd56d7652da8b72d082ed40ebc595d6bd2942440ae674804016a6e5d
OutRec = 0040001000040001c00010000c0000800020000c000180001000040003c0001000080001800030000c000300002000040000400030000c0001400010000c0001c00020000000034000000000000000002000080000000030000c00018000300000000140001000080001c000200004000380001000000001c00000000c00008000200008000080003000080003c00030000400014000100004000280000000000002800020000000030000000000000000002000040000400000000c00010000000008000040003000080000c00000000c000180002000000002c00010000c0003400020000000004000200000000300002000000001c00000000c00004000300008000000000000080003c0003000000002000010000c000340002000040002c00000000000038000100004000280002000000000c00030000400034000200008000280001000080003c0002000080003400000000c0000800010000c0001c0003000080003c0000000040003800000000c000280002000040002000020000c00000000000000000100001000080001000000000c000340000000000003c00020000000030000000008000040001000040001c00010000c0002c0003000080002800020000c0001400000000400004000200008000380000000040001800000000400014000000000000040003000080001000020000c0002800020000c0000c0003000000001000030000c0001c00030000c000280002000080000000030000c0000c000200004000200000000000001c00000000c0001c000300000000140002000080000400000000400010000000004000300003000040002c00020000c0003c000000008000280001000080003400000000000038000300004000380001000080000c0001000040000c00010000c00028000200008000340001000040000800020000c00024000000004000380000000000001c000300008000300001000000000c00010000c0003c0002000000003c000000008000280003000040003000020000400034000000008000300003000040001800000000c000300000000000003400010000c0003400020000c0002400010000c000140000000000003400000000c0001400030000c0000c00020000c0001400020000c000300003000000003c00000000c0000000030000c0000800020000400028000300000000240003000080003c00000000c00008000000004000100001000080002c0001000040003000020000c000280001000000001000020000c0001800000000c0000400010000c00030000100004000080002000080001800030000c0002c00030000c0002000030000c0000c0000000080003c0001000080001c0003000000000800020000c00018000000004000040000000000003c000200008000380000000000000000020000c0001000030000c0000c00020000c0003800010000800004000100008000380002000000003800010000c0002800020000000008000300008000340003000000002c00010000c000300001000080003c0003000040001c0003000040002000010000400010000100000000140001000080003c000200008000100001000000001c000100008000380000000000001400010000400020000100000000300001000040002800010000800000000200008000040003000040002800010000c0000400030000c000200001000000002c000100008000080000000000003000010000c0002800020000c0001000010000c0002800000000000038000200000000080001000040000800020000c0003000000000000010000300004000100001000000000800000000c00008000200004000040001000040002400030000400038000000000000140001000000002000010000c0002400000000000008000200000000280002000000001c0001000040001800020000c00038000100008000040003000040002c0003000040002000020000800030000200004000340002000040001c000200008000300003000040003800030000400008000100000000100001000000000c0002000040003400020000c000100002000080002c00020000000014000200004000000000000080002c0001000040000c0001000000000c000100004000340000000080001c00010000c0000c000300004000180003000000003800020000c000080003000040001000000000c0001400010000000010000100004000240000000000003c0003000000001400020000c0003c000300008000100003000080003c00010000800038000200008000380000000040002c0001000080000c000300004000280002000000001400030000c000040000000000000400000000c000140000000000002800030000c0001c00000000c000300001000000001800020000000018000300000000000001000080003400020000c0000c0003000000002400010000000008000000008000380001000080000400010000c00
Key = 11e452a7b206e159ac85ea8b6553d01e246d084cad52fb7b29028d79962091dd
InNoiseS = 2e6f8b71cc4ab67f9816984bce92458263794396bd66ec320565045122d1a427408678dc565386f2f993fb14e1422366ade64536811cf943271a185b747eb2d62d13b6d5028b755179d538f915bce3fd7b1e4a2d6d4e6bf29d06554a010502a70a516fd7c6564b323723eb2a8570ceb98603208a349c685ddc1366b55da84b801ec8a5ea3882c6668a394d98b4a1036946ad618f1cf427a9a05676dbc615acb25c53cb83a117964065618b213f1e4851dcf2663638315859704a44b5785bcff0f7fd2a6eff292c2950fc817d5a4b7bccd014d95c4565abf86a6e8cd2b32e9594482e46e505e57932d30ed6639853c74ff2138b122fc46f54c183f11858ebdb2b871ca916109922ea7e3556e63d95028c62d2652c0b9f35af121da795121d5872043711b6a56639e169eb41d9780f6462d140cc7ddeabaed49d9c4e4284d07132d92fc39b98a5c5cd278023e3a1fdfd8875e0a7a2effe4dd3e2897be58520d99c36308caead22987d959a480db2cb76488cf14e4c9bc92887d5107c6df91ab69abd9a11a50a91b41138c22ed8281c58ae49a512c5c203f563bc7950147ded01a7078f8ebeb324e6e305295522df6eb91035ace84be894fa824fe6415b664e1873f3a4ace6f2f5aaad6d121a489688d3c7d307ab2414b79822305f8842339540f42e089df2c1bf0620ec7a306f36b2d4b27c72439875109d6dfbcbc43358f068108555e0f7e2b047140a589cc4be815227c9a29eaf7914e381513e5d9d00fd3296ee894c9641d2b00e79f62f2f62d8b5ade28bdc26fc6e3711c2fe3694ec9c461e28b5524c59fd2a0ff2ff599c04d8b882f23a5ecf917d080130214c262d3826a616f093acfb64fc6c9c82c36708a628c652cbf0ec8911e902caa2e805268b8144e595f1bbfcccbdb8b7a64af5e101fb113e8abec686c1ee7c2a539593b6f80549be9d8b814f360d71d6bbeb569db2e94d52405b8895da9a02495a01ac93ce9847503e107f6b81fa598c539409a7873af606315f82b9eac49b68a6b9f214a84d58083e067edd52d167d1ea65969cb7a40299062a732d2fbfb26139570c97151187741b9d020113651e2ed0cc279893348b2592531a6a1874c317ec638b42339890205705a52099aebb745f2689c54954f32620598048557aafd940650451b5a0e246f683e507d72080ac8b92ea399023f4ca93dbfb54637cd0301171d124d34a48f0db1a2c5f5ae5725271249a1198347b724b22817f649fcc4b02ec374b10b0524e08a9a41771741c2234d6324856c1aad86051d831e62333162aa2a32905d618e76c353a496829e3cc7a07a66b975364907e6da5d983e65004a392b1b8ce692ce1b24030a6756d60f6972a2e8aefef7d761e15645043d7720d1d756d1713b06c16712716f9204e29b2f8a45172b0498328a0d1b8a7a664079123b9851059add99e2209b4911359f42659e24def8cda7bd4da1ae34fa7669f8218d786b8b9ca16520ad54b5553b92cc99541e6f51caec0176729687977979c4726abf5321344edd66f0e03bea512c6dd54b9d6c80f932d4e58e75f8bf97b3e0e15e412704b691334d10541cb7037eb653f084d96afa4c3ab78d2468e4242fbdb24b05db81815280ef458871dbad0c938719a855d80c3392506ac313b755e13e6d587d0e9c11775e8d588cb048f60c64c564024570b474ab83d9a8d2fc7a0eb465803aa2b643a15c59e3f156ad133aca6c9c968d1493d601fa59591c8d0aea49a697a2e7426c36d24f343b292ed2201bb1f2638a2923c8220e0321f081cf465f98b5f69ff3ab78574646e828487f40c6f4d7c28be30391f083e78640a28f7066ab9aac6138a106dc9c3497c38efbcf007062de29a4b7a38397d0305a04b5fca5f51ddf6b026dd9aa1ef88a394aea54f20be3800d488af630522dfbe8306a10f7178ce06c097a3d7ca62b7169365486b4a23c52c1017fd4513268e4a20c5702b8d624d028098bed550389ad8b987c26a0a0bca7478f3c8b5a4c926a2c10c34662de11b7a260539727e75304c0c28b15e7cc6105da18ab6ba720eb6e0bfce3b220f7f68bcbd845ac8c7d166a837c46714721c227b5bd263d2a6fd54c7a7f26267597953943ef22cb9607f65eb829b5e4ae84b1a263c69a77b16827a7dda44bad604831dee420100d2ab45d822cca55378fffc7377d57c381dd92661eb2271599a68f4a5c4811ad16f27c16103ee9e7a802e9011f7fa542f4799d65c448245424c9698fd3d10cde7cbcf6885f6d630e1a7248ca7ab16b6cd8d262e1cc20243d46c5e1c2aa508c22b6aacfa0a4b8c60e2056bc3365c5f3acc45c61b2d12778bdbaac7744423af4b32f52eafd9a7835400ae42d424d8a46c0c03acefe9a684f903f5c8761616cc82e05de264cb7278529f3c3255b8095f64a2f3f5299b3365efb356d856b04731a8c77845336db8c1952a6ee91b64578d620af6052a700989a2338041e767098c996ce97a6f9907c284bd4acd688937617003afb95af11447629d71222919bcd5b4204a
InPK = ac839551f2d26b42e6bab93668afac931834e5d0230e84f450cb25ae52a0e32850da5f44d42cda563e95a64f0e18636a43c50e0d79a7d69a15c5a43a9d2d8db99bd0a43d3d60cecd0ae499aa5c2280daa1ca09b927a8e84abd068e684d0f025d606f60632d85f70e7301444d1495351d018c690aa2ac9e8da8d598dafc87d4921adb9eec3818d91e981da53a9be7fb9053f5a0b107225bff688e01eb1dd0245d30fb2680b2baad0e81495bd21a0d5cf24b96b830b12971a0478902bd6277104e3b11e138b523e5d9d8d6bb4d099c66e92693371558b2ee3222f58db087a1ba2953c8a147b8b21714ece87242d47523c004071306b6eb14358be901b0a88d9e12ccc682d204533a2fe87b578b449bd88a6af1a1c0787a8914dc85ee81ae6cbd53a0f0cbbb3d7aa8965bd7c34c6507d3709211129d802c2eab3e3e1a589948130665b4ff9cb9a050701a0aa3dc62b4999b29a4b604205c0f995d27411260bd93abc5d2566a4b9141c75ba03e28e3223ed9a661bfa9589826a10d525b5332b59f6163ce559ac3cb9cb0352b55d633d5517885c0bb9ea5aeef9f0a586fc0a171ae5b5bf7f6576caa6067b76ab5682a8260d0be3c80219ec7746a9accc6ad47d2994615cae6590214b29f230cb881ec7d59c29be2c5380e3c15ef34a3543dc751e2182a4e397c6d02b0df746741cebc41e6d59f045e8a71086140c212aae224d53eda4812d3ee2c120ceaf7d82814a163dd23682f6902320372e3dacd1cdd4b2d835d493300ec572944d44ee0892d712c144c4706ac47a5307abc08f9f0fd905a6b26af28c050232fe707e08c8217774612e9d5e9206697b8612bf2bff7d50282683ca6d3ecb088bd3eb917e37e4a449a294c6bfa5b6519a0dca0101872c10efed1d9607b102cdacdd893c72e804a96781ad08c89966fb07591696a389948363450bbda9b903aec4d47be629143d7ba1b2f260b88dcd182d345aec4a928766c5bd89b35980fcddae4b80f322e9d2b87d0dd9539330d82c930b15e0bd9b05a73fe6426e9da685b540e3c1d35448aa4a0119bfa30c6326877abf850ed1822ae000132b1501a69865329c74a2b03eea490f6fd1891214d73ba6a4ca5e0db87c70c63a619f7075d348969eb46bb9f5d34926df75586fa49f3cc3975053eba33107a714d627075883bc44f6267ce16971ac5f0ad3c481f421afc9c1a12aef556392d2497ef884abc7a8b8fde85229d42896abbe913b23ec32a136ae3117fdbeca943f91db8c5c41d0037e8a7bf42eba1df45295ed7cc876cda4b07e25106f97435614200e2a74c5781987770c2d0157e558cb64c20029d6774853e2c5da3da0a0973d4bd53e35f96c171002e4312fa6c518fc909690b8fd06436e5b8da9dc297c8cdb7146daa29ad15eefb0f2168b8a3a6c7243a8714106d35adaa29206ad2509ee61f082c5739385d9fcb0b2ab0f5fc8dab55dc670484871c69fcd361987ff1cb6797ae3e51d9974ca6b5087f9a229519e9008ccbef4ab6daa24fcae95be3c4a1167b5e1c460da56b642362e7ed8c7eba8100d793e52bab2082b40e3d8340905dd4dbf660119081160739b281cd16f7a8bd020f69e06aa79505870771fa4219008b9d1ca1b0bd28afe029f299e037dd82c0aa17781009591ce628242f74a0ba1526c100e26caba892868da9680b07904545aeda84154384886a4d55118e7948fa2cdaa586f29c25e4fa317ecd3a995c793921106a7d8dc3b2fe3432214bb339614a579661dbbbf07104afa6ad0201ad4b6fd80e90427e6102eb1c02c4d62fbc25464760b6368da0fcb26cb5903eadf6d284328d9867ce610a026d65c1f80a4c7482799e1d3827f945dc6f4a49d6e6667ac5ade72d8804a81830d49c85bd9c431d38372a90198463d2f17a10f1961aa01d0495bf6e8c098248ae5d0740d7c7b266481438e49bf44edf5f9ef345920339a60495c70613aa2ce2988ca67e66572267dcb1aeeaa6146a2a6e69bbe60243fbe2141a6ff802bd581a4d8b351558608ad1db2f0a818c7fea8b49d3e3b17779ce6b5a84a100f368826b15462f0b9f466a947171ac8c0f214f5e25d2c9fe3374e4b121c82d26b45a6fd122662880966b07ca3ea54d1a6c98ae4071866a2c028bd745fd5c91eec2164bb00c1d19131769d196b8f513cec2dbdc562ca2d82261860115d693e232ada6f8446c073e4c1529d34479a5640c648b0b74d1da3a480941ea584d42608bb8e7ddceaed49a9d81d30654866abb70e1924db0c615932f463b749253a4981050ea498ada4edd6728a44538f7982e1b6927d637da0ebb593aa5fa1813c7834027309d1212c7fa29f7204d1da46de261250ad8c0bb725f46742c14f0881d88702fa43efa706406e7c5082bd82a03c92240a01c115a6faef5830ab109491aeadb01ec562b67fc5ac3c529a9db48369788369013d4d298ac375ed33e44371a31b21585c7112c85aae85ea7206c28ee48a7c253561efd56d7652da8b72d082ed40ebc595d6bd2942440ae674804016a6e5d
InRec = 0040001000040001c00010000c0000800020000c000180001000040003c0001000080001800030000c000300002000040000400030000c0001400010000c0001c00020000000034000000000000000002000080000000030000c00018000300000000140001000080001c000200004000380001000000001c00000000c00008000200008000080003000080003c00030000400014000100004000280000000000002800020000000030000000000000000002000040000400000000c00010000000008000040003000080000c00000000c000180002000000002c00010000c0003400020000000004000200000000300002000000001c00000000c00004000300008000000000000080003c0003000000002000010000c000340002000040002c00000000000038000100004000280002000000000c00030000400034000200008000280001000080003c0002000080003400000000c0000800010000c0001c0003000080003c0000000040003800000000c000280002000040002000020000c00000000000000000100001000080001000000000c000340000000000003c00020000000030000000008000040001000040001c00010000c0002c0003000080002800020000c0001400000000400004000200008000380000000040001800000000400014000000000000040003000080001000020000c0002800020000c0000c0003000000001000030000c0001c00030000c000280002000080000000030000c0000c000200004000200000000000001c00000000c0001c000300000000140002000080000400000000400010000000004000300003000040002c00020000c0003c000000008000280001000080003400000000000038000300004000380001000080000c0001000040000c00010000c00028000200008000340001000040000800020000c00024000000004000380000000000001c000300008000300001000000000c00010000c0003c0002000000003c000000008000280003000040003000020000400034000000008000300003000040001800000000c000300000000000003400010000c0003400020000c0002400010000c000140000000000003400000000c0001400030000c0000c00020000c0001400020000c000300003000000003c00000000c0000000030000c0000800020000400028000300000000240003000080003c00000000c00008000000004000100001000080002c0001000040003000020000c000280001000000001000020000c0001800000000c0000400010000c00030000100004000080002000080001800030000c0002c00030000c0002000030000c0000c0000000080003c0001000080001c0003000000000800020000c00018000000004000040000000000003c000200008000380000000000000000020000c0001000030000c0000c00020000c0003800010000800004000100008000380002000000003800010000c0002800020000000008000300008000340003000000002c00010000c000300001000080003c0003000040001c0003000040002000010000400010000100000000140001000080003c000200008000100001000000001c000100008000380000000000001400010000400020000100000000300001000040002800010000800000000200008000040003000040002800010000c0000400030000c000200001000000002c000100008000080000000000003000010000c0002800020000c0001000010000c0002800000000000038000200000000080001000040000800020000c0003000000000000010000300004000100001000000000800000000c00008000200004000040001000040002400030000400038000000000000140001000000002000010000c0002400000000000008000200000000280002000000001c0001000040001800020000c00038000100008000040003000040002c0003000040002000020000800030000200004000340002000040001c000200008000300003000040003800030000400008000100000000100001000000000c0002000040003400020000c000100002000080002c00020000000014000200004000000000000080002c0001000040000c0001000000000c000100004000340000000080001c00010000c0000c000300004000180003000000003800020000c000080003000040001000000000c0001400010000000010000100004000240000000000003c0003000000001400020000c0003c000300008000100003000080003c00010000800038000200008000380000000040002c0001000080000c000300004000280002000000001400030000c000040000000000000400000000c000140000000000002800030000c0001c00000000c000300001000000001800020000000018000300000000000001000080003400020000c0000c0003000000002400010000000008000000008000380001000080000400010000c00
Key = 11e452a7b206e159ac85ea8b6553d01e246d084cad52fb7b29028d79962091dd
InRandA = 16598e075b0e7c09cd899080a945dbe249066492b8c9829f42e7d131c5017540839464989c68ba38dd2365e97c6b03c83f2fa68c84cb8c70a05e961772ccaf358dbbea4f043fa5d8db73c062932cce55f07ec98cfd84b1b2d13c33e94d94a616318b1e400f42b7424e256655d1d810114842d92882dd4d286a2f9ae8e065bac291bb133d462c531c4b902a664d5d31817828ae784b9dd1cdf193824f5578345a33b34a07e7add5246d933330f9a25b72c79f57920da7be25408b26b42a142248c4bec048ada2ff02fbd9414ac16c490ca636082e27c7e502a3a027c822b0bc558d0a48680d89ace313195b8bbd5e7d144d394890594a07e8a6f266562c628744a1e85492e97bd9444d7a69dc74c3005053d81ce2f358d54c84159f48c0f26c3e58aa2a3fc012fa5ada92e0ee63a39c189b61b129fea5ea2243e077e598f9e2dc95a8e31c632ab1b975740685e5d389b785cb95e572e6951f11e401d598b359464a0645882375c667e416c4b2b684269235a29890d85cf6c16c554501f709d09654a6001ac7a2ae52e3c3f275e01eb0366ff80bc34d96a6a877a925690ead51da259710bbcc1c4675b9a97ce6e8b93b4a4c93e7d95ba2ca42adc3a0a5431b05b0e818a04a655db5986514d3b9b905e50c0e9919818efa1d867ab90e190b0fd55704f18791143822a771711289a7009d2c0eff5e09f99c520ce791ba00c8046a0f5e2f30af489c565229f99bc66a42608345769a353f4079906d6d27334a5b11eee821a398b56ab310791d86d5b2925c62ed2d17e28fb89720d180654c394de526dc1558545a796807d33f86ae96953d06dd2a5913a0b9a99846960ac6f6453a125eaa0f4e475a82149485569bd5261084e76dca5291548ccd22f4a2f218d5084342387c1a78a04403c1b8215a9899859e5c1c75e359cace8069e4c85aa8b6a846218a4338ac58447758cd2807c8b1cedbf0319fba190d49dcc554788558c943c65ab65edb113e3656ca1ba6c6344910d26a441f41426afd7bfa103353037057396ad70237d854ee80661a406d0b85c29bca460cb44b5e90e500d10c9dd106d1a10d49b4046178ce003b18eac14517c5aeb2854ef8fcd6362a0e3513cfd24c1f151045f0f1a7fb1554283a5682ed6e75f1a0edbad88f822632b90be8d458c6dcbe1f865f4b265ab27e2fc4bec75eee311261e3f52264014656094205b193315be6a3e5114663429e8823697d504b71fa9ad615acdd36625720ab40956501d998a3fe8037c7bb75032a4d53767b701ab3c150179bd50aa5553a4a272e48c71539d7da256e041ddd9a85b0a8d9dcdbcbdff94d80a4d8e5cefd292fe938f04cad77ba2ac86b57dc5660ee05f7220812ba6a70a2ca1cbc5f1736a5cf293f1acf96268df65e3e92362843d81337c88053aeed7ab2831b98f8494190eff3272d687c171af50468c49578a05a7be6c237460f93f9ab7553981761d483064233e7d4fad5104f5b001ac03ede1776ec0096ba323b765ea74a8c2d9a0d91e130ac9a4807dc6a8376fc362f4645d614d80f3f55e2cb49866a62ada62ae74d9288160bd5cc1d49b88a3326c5f447f9d47405a1b8b9eb23bd03c03e207c09cb59cd4dab8755d8d016bd198e45d1d5ec6017a61fed12b719970fda2a89874662a7e16ea11b185377c37977a1ed0af78fa3042dc17e192e4b3b2f7212964e36d357555d445348c2759d8e3bc1ba94d9e047ad8a40a05bae9f918187039bed17086ea457d1954d4c5575e9ca58040c129bc6fef20fe628d6d8eddead751729fa7d710802db77c1cdc47176512b098fc524024448230e4e95880fb5e375fa7f8300ff67b05861b605636aa04c167b4700b50656054c4ca323534921679aebb3be185412cd9ec0218046e224cd1b886d6a74d0e4479fe502d7038ea08a9a67da97eaf09e59046f6efa65348085d80d1832ed720eefc294365dad860b4afb412a0d7109e90f224cf87fc84338e15ad99e4d523651e0202aca201e98c9e440a4a07274c8dc95146a2e37a8841b6b6d48431f88373ecb7ff13b2c1c366aacf477e58a33af37c3ad1e8e708a10e5685878ce5db4074838b68907176239b6bfba643d88aac92bde285cf142952a135fce2308d9bcfcdb21955eb0342b6f9f18caf8b6f408c6c15cb976108097ba52ca2af509b489d379b27deb0470e6c40cd62021a74cedaae3dda546f6b86c1e5271d011d9145c55d407b359141d5cfeab5c820f221d199764fa369242efdae1210dd7e4cc66c3deb0ba8442bbd27c0e688415f2ddb961e72044b8846c911816b87384260dc81b717a5eed06724e8d5334008fcce70985b3c29166cd5f01e2901f44ce0f75ce0038d48353c2e7512bbc5acce012b90984d2558386a2a33a2e69a3c68e3daf841876a4a668f25cb061b1dc289c863b050351a0ddd787e3f9711d92e61037f180b0820adab8afd5a5fd2e7f198e6e1b9c8291012ef543585371128c62917167ba43a96aa42b296958753a91d16f5cba922d58cd8d2d1621922d
InNoiseS = 819fc864be3149721adb2aafc882e380dcf06d756412c8a01283e20e6ac1a396c0e14228016352fab19a6b41009a054ebc5ad9a4dbb34014e1df2a7388be6d9593d71860109479801ea9c464ba476edb713664a3245822999c2d8490db2aa7874aaaaf4cc0a1a3fc4617ed5c86f25985078fe7d6f791984d55944621aa86fa6d07763f2e57122e50d89235b3a5ad9bc47684b5f1a0d9005b059b70038f319e31137bc116d7229cab130a331403eaa76aa2a5225b7c9e7f57470b029ebd8a402f55a83e10d6290c391cb90c549c1de65bf83ac64253674c2804701c5bb1e616bc806b72224d8d1c43e049ca146cae42c75569c6797073dcde9028345ce38021a535daa7288018e56b16406a4e8869bbc656070e2699625d14ba996e81431a2d0a14e2405a082e40e13fa2b37a1ecf9a3923a68e1d990b812a1ffe9a674df40029747d846ffc894238b9279901c21489b975aa670448a4766a484918ed7551f9ee7a66bc26b88b002c7bd8f51f9b8c42a8e3ba214815bd687648459f10f2a391856ec3c5bc1a358980b1aea10ab26e430663ecc38018323f2c36daafaa1ce252774913ac30b6d27564c5c20e11e74606b1c1075ba60e451756591d443ec60ce49398d7b4ba3dd000630aab95b8111652e0c110fc04059a68a5c17c5e0a8382f3a32de475f01082a2fe62264b6841a44da669475348dbfda93a9304c502abf4b1710a5b27cc39a8f0e705a4633c5fc65951e4c7f86525c0d760079a75aa587a32ff0e9b82ccfb324a7e8abe9eadb940e10da2ce00f82362b26e8447a1eba21643c0b0e02a2d1190ef51db4a5969aa5c50d2bbe64d8fce2186f2647dff4aea76b78d33fbdf7d74bfca0cb20125eb5a74b1b26d68e3531db09f634bd134603438492df7c4d1a7402f7559e0a4ac8b8e0c417569478eae95226a747d7ead94390c5633041b27559d1e27bfe9104209897e3700edeba72d6f496cd87b7d446a1569b490dd8abadea4096b67396ec8c269bbb7f264bc9d9af9423829a149c3433b215528a90bb1a44878a2c84a35e23220eace1072dbb03c7c1f6059da627e9ca408c572b03ba1ee726739d8b32229f4ebc87c9b7fddff1652a24d02868c50f7cca61da9fdcabf6e733a1d90fa49d66fe8e73d80b0b6a567ace5b62b4e12cf1c5e738199881795ceabe2a517ab2009a90999ac002a40147ec93511e5b484b38213b09200549e1e386b9aad924605721498c0c2105a5129c0877aefdc25319380735eaa680a97c0b51abca6605a9af4d9167e87cb14a6c7424b4d427fe4db4e5fe9867004833a159069a3f6592c232a4e2db38512bee2a9b991d415352b26d83115e92d6567e0d943c67f8ae7b694c1e6beb1e857267311310426713a842e46aec68c0b4e9825a3133273c76475804aed47f31c36f8eba860a600967953152372cc1cdf893e325ec92d14ca45a9135a9c5b5cab4413fdac9f90cbd74be6beeacb6b248d328f081efbe6f268672cc244c04fd6509f2df12628b4a1c9e614eb1c6157d8981e9a6a019e2cd745733765582e92a518b2785056c7e932fc860f162c4c62e738baef86e588e3155515e0fedb0bcd997094d93b122d7d54c01296704e38b4ee47d0b67d5cc784f95a3b845969c1cf9ae3364a314f8aab0a19279c1784f6dfdc77c4e65fe5f43a77a8cabed319cd69ce96ebe04b254465da81e561103b242a2ca971927371d985327b850c998965327d18273f66c4f98281070e940ddbe46e8a4dac8130c4690b561f7193b3518cc464f096e720097dab1a17b4d4bb2ad6abf84b39246f470fe4589410a52888c6c00163d16df7c2225ea8071b9154a0fa340a29cc4bae8a37640c86f9ee7ebb1fda52040b09979a85a1b09f5432c884296191167e1802949857d1490c862ebaf40104a9cd22425338a27de46c08e34299090679fb115d473947831052dd883805d70625944e1723de9217857ab05aa2f70461982527d7d07db403b960800991fa06d7299a77447043eacdb52036082403867f0a182031179cedf1de9d0a5da71782718d6c874dd359be309f7090a94835e10f732c9dc9dff59abe1ed8441680117811f2d909d53a29a26bf47756444424f548e89abebaa25652e10c6373127e489d0d2123e278d05c842ac99ec321b6ed6af94eafc6216a54f62f00e0dfdd44b40eaf85cbed5819c0e553537182b1d9f9548c0e08845ffe8aa53631f76814d759a55fc9d020d2148415b61634864e6e590f5fec73cbca732c1fd19329d90e7821dd106515442d4698b957f697b2c9fb652826283287a064ae861c9c96c58261c20c51d642c5e0e09e84288dc2fd16550787a8d6b1929adfeb1b2392854977ade19af270825f9a20c6c2c5685b08b4f7c27123494a0365bdf50d8acc29f53afe2ee3a743c0b19d7d6613a39a19a20884d98086a5ae633e1a150a2fe2ad5853614b3ce94fbe401be3223d260a5a6994c321366e6daeb06f166989acf825aede985d4ab7b1948d81f7eb27e946948f5dec13765bd203
InNoiseE = dc9f14a1206da08c2b96b75e5d74d3c5c6b5f5583beb6d67d5db42b7529d062a43192d945a769500e257641e1eb74db99eff89ce0812c958738c45d753c8389d535e1595467b57cd6e75ddf9ae2eeabec6d119545bee4a6196916c14ef934756eaa4d015a783ae9940728d687223447c041c8f60fcf4440cd1c9f138724147a17c2406e57b5a054230653890a014e2200fda3ed3ad0c53ed18aa00a861b66c0c1be983737326320dcc84f914fde4157c48aee7686552c2261e580d988677c1ea18d7e04b711932d0789075b3d67ef34b1e1745c7fc597dc422258faab8edd85d2917b762136a62d5a61df989629f3996cf24d7d240d4d2e5270b5927b727a242f16584c15a142a5fb87b955c5da059b82bdd509374d53e90c5899504c506979f4a000287b8b7f3ce8d64bd066bae117ef3b4cc0caa97dd8614f02cdb57559a11bc222e5cf882026c3597471cba5cb653c665db66abe67073cac8d2c8325d5cc5d259a5a88a1a03e6f8d7c9a7991b83f2fff57054acd8e0434d1729989d0b7b4d27802550654719b79a55abe58736a4646e36d2a5e19307517ddb4b2c69f9203a18b07cadc39603c759f100b28f9c744345085e86f578829a3c0c0136c75dd209615cc399276171e448b626181aa575a7ada14b7865ce62b06363995a0a0d78e07414204b9e1af8d78c3a27d9c9ba54401744ccfd969efd00cf4f5e96c2e84510006a52908881b0a04ac9bb31b2234f769791e92dee6dfa77d71aa97c56caa98b3e4b5029324b570da91d0a4a64f4f518e4e7d660a368514a8750306af83e034d4e975f58765381a7e5dec50c91a68548352e8fdb40d000a50da373a1ddf1eb2227f6004410fd351756e2c760db9e038e9a0d69820c69ea177345b70e72d0edae137446b6b1a7d584fdaa4a50e5af7ba61c5c1386fcfb2325b87546ce1a7901148edd875b5e1693196d7f29c67caa9ee9e604ee0051792302fa7ab812a86b811590deade5a89be2e1c61e6942c8e0bcb2a5435dac7333688b98155b52936c79b3e67753ddd612e5486fa59d92763fceda460d1d59381203fb4bb13b8567f8c5e67e4addc587d9dc78923f0ba902cf015b43a7976751042dd05d3fe87fe0abdf41a4272de09d090831035d094c05528101dffc53501698938bb9a0889fbe266c1a134cd13173883104a5c830f49671923bea9f66507653f2e59f20ffc9bffe43149354198f24d52118bfa0a07f551eba245d46328f5bb79920816d025b28f90d68dca36bca1b393db89d028ab2264c00e3a03a7a74361c25ea962bc147aa255bc3bf2c77d6666e90d304b1298044ebb50076c69f08669269b2b2a7a846ae7687facc9d99d61a24c7d891b6e3e6a78be9343b1f269d6ea8f6a4d588115051bb453c2d34346b7a79a58556af009789ea260e668d721a2dd14f429fd991d2dab08ca44234ef7896eb097f2841493f565f5eb649a0b39425af5a19d089e3c4f8381c2e38dde698602229a5a613884a92517393de89e3f234930fc3c7da7b7299566678371b62a790c3cd64565e13279015e537fc63f64ac4b96ee285de818ea8dcd6942862c83b377cb0d609db996ad60c2d5023ab5c6aa004acb86271a03f8e5c8e514d602662e42a106a7602ede316d3a7e919b7984004d2aa8494644a5390418174668b4b48104f86d795c02aa93768c0bcc97721af092017faa5720a93ac8218b3c855460c529b5184a70fe4ed355b6e1fe00dac5942995d9c6f3eb5501975e22cee248321b59b563c913b7027bb10f3716fb294d6dea9a52bdc8258689461c92016d8de9bbb8390344b9506e07f2d2c95245a8762827f034ab6e53f38a8aba872aaefd589ab6c86526f6146e94af09417a48a04eae574ffe533a3c53fe9027a0401aec5453b0213d49917f1ff3294cb9d911540a88b630cb7a4bf0057ff29b983bac2102ea58acad6ee9cdb1536cb7e7203b09c41bb856471b9d0ab34d965405f6ca24854f4188b2854e20fad6ae8c404438b82214f62cb51ed5d5215c430dace71863c580653ad309f6f57bc0904fe9eab19ba11ec50560ac22860d8086a8388c4c2682480fd279c065c49ae208d96f813669141199af5786eb58e94d946db10b4dc5dea981fd16eee5dabdb6a464ad963c55204f5ae74085cb02e280e10a6a588fce4b437c804550058a89206401ad81d8b75067648d3ec385e469977e55e9fe2a37200dfdeb3b02ab55178ad12ad6ee99572423088aff8253681a19d4a1d699d554b1ba265a196717aa00d4783b8a47c03a42fa06c64a864157884e740378be46f772c092f6fd06f39d44850639e8dd19af8a2a1e8344a2b786bf7d7ca2450c04965e049919acc92d2d2ca212b5c3be0d035010bc478e028f390147800bb62560974c9222cd0e455d7ca5b6f6e5b87b386a6ac44b054f0f416550260a7fcc22465e7cb3200e297144db7e1f5609ddc00bb25bc753329a4c764f29c2f6bdcafd2fba66e6809c32124c5417741744090ce1b6828d00370e6b760a09da6f73089
OutPK = 7b4db63984b59c5f4c76202fbdb360ed6a27ee1d9395e7721787e4b0d7ed20c9937214a4690ae10bce3a621f08d37706945b1912e0dfa911bde2a1099ac611131dcff41abe5a16d33978094874b852743799d6316c873bf2f8e17827ddac9b33da6a4a5229e01e6d85f1973f4aa7cdbb45934dcb680a625fc4a715dfc0804e8a2f644694390c14e053a8ea5e65a4168a52629fece156b3ab995ac385c7a8ab0c60969ae05563956fd0a3f1d5b009a05a5c1ac384f85c8bafcb9bc3d856de6f39e8c7f908d7acd743ee058e38cad1b0640c0ccd2e5a13e640bdac1dbac4a08cba19038f49175817e00d69092b26395a96be87af3c8bc08cddf4faf21c19147e08eb1d796ec96c624b657687552b702164705782cda3142213254414a6bf0d17edaa692690ba78c4e46ab936d03a7dd785f27576754a0dfa5079517c0b264a20f65c1ea211870a0af071e2234e967a70945e01fb9460cc9b49d66e1b253a2fb709d674c45e588f2420013abe918e4c09f9e1e9aaf0d91daafb158193c14e8622b583dea1a3a8f6997ac5cbf640d0504e3629b1387e70286a244300b4141cbf9e45d87ec26992ecd7b44de2a2b02fd2aacc9565c990c0e300407255e04901102446e3d128aa684d878a1a5d087b51af20907ddaa44190d7113d7af655b7e2244a96b1117df9ce63e5d4612ed0d953358e81178b65f0c46d5e8abf414518169e5726247cc0298d140f2ced8059baadddc21a1521468a0887b09860f8011defcf06879573aac97a8084aea2b915cab6c4f900de1fb7e164b97976219178e4a17abc1a8c3938e1744a240f7446627549176f66c2e946becbaa200c90ba07a892607910363558ca43a9da560b8742667dc981b842dd07b76d2bd1abdc005bc1b1b587b3a3ae4d39bb4d7c218ad27acd522d71dbe953964468e15cb5464042b45118eaaa5fab1d3bbc917d9b57b33be2e56dc062804bb5064fd48b6d68dad551e12ff329fdc5971813121aa4c48fb75f30236d4946d593c8a295900f6a49f143d62a5a682ce686eee16457ef90380cb61d09a1ca514c4646ae5f0a1448c5bec2996f1328da72809e3f0a13344d5e6699786b386211e170b44cfd985ed473ba2a962e4c6b6170a53c638584dcf0438516cbac9ac1c028159087d17b8b403a949a50a0d170aa7d66cd5a97c83231012fa4c49a724b01caf7839a45655df3f7f9caaa192d94e9b40d05352137a9d2906712c25bda8c5522a59f8b190c400b2febbdcb1cd0154e1fe59935842a3cca3aca97fa46fc081a08a37aa6b310e6d07f3694a60ee142b9f86df643256888ad5540817fd3abb4a4ed88b4e8d5b983d8db27e517d1964cdbb377e6681354c23a016dbd15ed9fd287b084b4682dc6bba72e2de24eecf9f5cd0a378bdeeb477da863408e707af9b97424832a69d0280767bd10aae8be374897d6f70a107acc5aa5e4655c32ccfb288dfe6dd0c44434bd15b9c7a02a2565f96d7ce38126f3a425ebd133d55d561bea5a2db19619167e2614a93ca8b0bc4576cb1d225ca8c990a36a2ea86d4797eb71d242f3e04b6177d932dd4ca7a01974636342dc239a5d393f141f610fbc35b243c057a1fa80a3d83c10620c6c880cf9a354c25b368d98d636f1521524c7a3a3be0757dec839ec3c15cb66efa82c8931c384581a6d324e13e471545515a2a008d9c24b857e32659980a40e3a39197029b8e452aac99aeaf5b58651c82bb0ddf68950654c4be82837d000daf1e4c89d1691c757a4cd57db8e0389818c6a80492db4544e6ab764a0181ccead3306e1c0f2665d4e28d09ba7ba513047c501763678ca9bb0a8a4967e4f6e6760d7ac58e5e2ccdbf5784ec84a148052593d6c89b4b3c70411e51bf664fed6af66d220838cb2769565667b2b0a3b31c598f8582078a25092164275aab4178a6a1d083f0f50237a5fa63d3080ab2510b04cd1c42af9ec321d566d4e6851d0a919da49323d196a314d83d1aedc23b6d5140825e54cfa8b1032a0a88ec1a2b116eaf51d0c050c9011862c45c69c9106d425bdd561a415100d401e76a728de8c3198d34607685d290f30c5c3fc07ca07d8f779ae929a0bd3c17eed78e8c472892f3d05a6c8051646c4912f11efba3cf0a561ad7b3697468b2f5be4b20a68884a82ed4a2978b49be5983bc16462b3ea04453521b824c33aba2e5d0e4a4b9c753da12c532ba88993f4507561f2fb2c7d9339043f727ba4749d97e350de064eeb539db2c10d2282adb54908adab2328dff4082d7d85eb194820ed3bbaa9aad149e6055d1ed5335ca8adebd9703949ba1a3981bcab3816a0bee550455fa4343a9c9de43ba673cb1d1f301f9a48978cce66895db5be1ae4e9eeb142f405863228b0bf932afb804ac87f5d8b3eb4c1ad4f4919410b998820f86e35d7d54d60292897130646bc9a888d65e3491bab5d5ba4cd0c74888b94e0d66445e9ef58566b568bd6847bd87e141aec81e3009ef60d4adc1412ae3d81338be513737c6244aa3478125159186387db3d8875
InPK = 7b4db63984b59c5f4c76202fbdb360ed6a27ee1d9395e7721787e4b0d7ed20c9937214a4690ae10bce3a621f08d37706945b1912e0dfa911bde2a1099ac611131dcff41abe5a16d33978094874b852743799d6316c873bf2f8e17827ddac9b33da6a4a5229e01e6d85f1973f4aa7cdbb45934dcb680a625fc4a715dfc0804e8a2f644694390c14e053a8ea5e65a4168a52629fece156b3ab995ac385c7a8ab0c60969ae05563956fd0a3f1d5b009a05a5c1ac384f85c8bafcb9bc3d856de6f39e8c7f908d7acd743ee058e38cad1b0640c0ccd2e5a13e640bdac1dbac4a08cba19038f49175817e00d69092b26395a96be87af3c8bc08cddf4faf21c19147e08eb1d796ec96c624b657687552b702164705782cda3142213254414a6bf0d17edaa692690ba78c4e46ab936d03a7dd785f27576754a0dfa5079517c0b264a20f65c1ea211870a0af071e2234e967a70945e01fb9460cc9b49d66e1b253a2fb709d674c45e588f2420013abe918e4c09f9e1e9aaf0d91daafb158193c14e8622b583dea1a3a8f6997ac5cbf640d0504e3629b1387e70286a244300b4141cbf9e45d87ec26992ecd7b44de2a2b02fd2aacc9565c990c0e300407255e04901102446e3d128aa684d878a1a5d087b51af20907ddaa44190d7113d7af655b7e2244a96b1117df9ce63e5d4612ed0d953358e81178b65f0c46d5e8abf414518169e5726247cc0298d140f2ced8059baadddc21a1521468a0887b09860f8011defcf06879573aac97a8084aea2b915cab6c4f900de1fb7e164b97976219178e4a17abc1a8c3938e1744a240f7446627549176f66c2e946becbaa200c90ba07a892607910363558ca43a9da560b8742667dc981b842dd07b76d2bd1abdc005bc1b1b587b3a3ae4d39bb4d7c218ad27acd522d71dbe953964468e15cb5464042b45118eaaa5fab1d3bbc917d9b57b33be2e56dc062804bb5064fd48b6d68dad551e12ff329fdc5971813121aa4c48fb75f30236d4946d593c8a295900f6a49f143d62a5a682ce686eee16457ef90380cb61d09a1ca514c4646ae5f0a1448c5bec2996f1328da72809e3f0a13344d5e6699786b386211e170b44cfd985ed473ba2a962e4c6b6170a53c638584dcf0438516cbac9ac1c028159087d17b8b403a949a50a0d170aa7d66cd5a97c83231012fa4c49a724b01caf7839a45655df3f7f9caaa192d94e9b40d05352137a9d2906712c25bda8c5522a59f8b190c400b2febbdcb1cd0154e1fe59935842a3cca3aca97fa46fc081a08a37aa6b310e6d07f3694a60ee142b9f86df643256888ad5540817fd3abb4a4ed88b4e8d5b983d8db27e517d1964cdbb377e6681354c23a016dbd15ed9fd287b084b4682dc6bba72e2de24eecf9f5cd0a378bdeeb477da863408e707af9b97424832a69d0280767bd10aae8be374897d6f70a107acc5aa5e4655c32ccfb288dfe6dd0c44434bd15b9c7a02a2565f96d7ce38126f3a425ebd133d55d561bea5a2db19619167e2614a93ca8b0bc4576cb1d225ca8c990a36a2ea86d4797eb71d242f3e04b6177d932dd4ca7a01974636342dc239a5d393f141f610fbc35b243c057a1fa80a3d83c10620c6c880cf9a354c25b368d98d636f1521524c7a3a3be0757dec839ec3c15cb66efa82c8931c384581a6d324e13e471545515a2a008d9c24b857e32659980a40e3a39197029b8e452aac99aeaf5b58651c82bb0ddf68950654c4be82837d000daf1e4c89d1691c757a4cd57db8e0389818c6a80492db4544e6ab764a0181ccead3306e1c0f2665d4e28d09ba7ba513047c501763678ca9bb0a8a4967e4f6e6760d7ac58e5e2ccdbf5784ec84a148052593d6c89b4b3c70411e51bf664fed6af66d220838cb2769565667b2b0a3b31c598f8582078a25092164275aab4178a6a1d083f0f50237a5fa63d3080ab2510b04cd1c42af9ec321d566d4e6851d0a919da49323d196a314d83d1aedc23b6d5140825e54cfa8b1032a0a88ec1a2b116eaf51d0c050c9011862c45c69c9106d425bdd561a415100d401e76a728de8c3198d34607685d290f30c5c3fc07ca07d8f779ae929a0bd3c17eed78e8c472892f3d05a6c8051646c4912f11efba3cf0a561ad7b3697468b2f5be4b20a68884a82ed4a2978b49be5983bc16462b3ea04453521b824c33aba2e5d0e4a4b9c753da12c532ba88993f4507561f2fb2c7d9339043f727ba4749d97e350de064eeb539db2c10d2282adb54908adab2328dff4082d7d85eb194820ed3bbaa9aad149e6055d1ed5335ca8adebd9703949ba1a3981bcab3816a0bee550455fa4343a9c9de43ba673cb1d1f301f9a48978cce66895db5be1ae4e9eeb142f405863228b0bf932afb804ac87f5d8b3eb4c1ad4f4919410b998820f86e35d7d54d60292897130646bc9a888d65e3491bab5d5ba4cd0c74888b94e0d66445e9ef58566b568bd6847bd87e141aec81e3009ef60d4adc1412ae3d81338be513737c6244aa3478125159186387db3d8875
InA = 16598e075b0e7c09cd899080a945dbe249066492b8c9829f42e7d131c5017540839464989c68ba38dd2365e97c6b03c83f2fa68c84cb8c70a05e961772ccaf358dbbea4f043fa5d8db73c062932cce55f07ec98cfd84b1b2d13c33e94d94a616318b1e400f42b7424e256655d1d810114842d92882dd4d286a2f9ae8e065bac291bb133d462c531c4b902a664d5d31817828ae784b9dd1cdf193824f5578345a33b34a07e7add5246d933330f9a25b72c79f57920da7be25408b26b42a142248c4bec048ada2ff02fbd9414ac16c490ca636082e27c7e502a3a027c822b0bc558d0a48680d89ace313195b8bbd5e7d144d394890594a07e8a6f266562c628744a1e85492e97bd9444d7a69dc74c3005053d81ce2f358d54c84159f48c0f26c3e58aa2a3fc012fa5ada92e0ee63a39c189b61b129fea5ea2243e077e598f9e2dc95a8e31c632ab1b975740685e5d389b785cb95e572e6951f11e401d598b359464a0645882375c667e416c4b2b684269235a29890d85cf6c16c554501f709d09654a6001ac7a2ae52e3c3f275e01eb0366ff80bc34d96a6a877a925690ead51da259710bbcc1c4675b9a97ce6e8b93b4a4c93e7d95ba2ca42adc3a0a5431b05b0e818a04a655db5986514d3b9b905e50c0e9919818efa1d867ab90e190b0fd55704f18791143822a771711289a7009d2c0eff5e09f99c520ce791ba00c8046a0f5e2f30af489c565229f99bc66a42608345769a353f4079906d6d27334a5b11eee821a398b56ab310791d86d5b2925c62ed2d17e28fb89720d180654c394de526dc1558545a796807d33f86ae96953d06dd2a5913a0b9a99846960ac6f6453a125eaa0f4e475a82149485569bd5261084e76dca5291548ccd22f4a2f218d5084342387c1a78a04403c1b8215a9899859e5c1c75e359cace8069e4c85aa8b6a846218a4338ac58447758cd2807c8b1cedbf0319fba190d49dcc554788558c943c65ab65edb113e3656ca1ba6c6344910d26a441f41426afd7bfa103353037057396ad70237d854ee80661a406d0b85c29bca460cb44b5e90e500d10c9dd106d1a10d49b4046178ce003b18eac14517c5aeb2854ef8fcd6362a0e3513cfd24c1f151045f0f1a7fb1554283a5682ed6e75f1a0edbad88f822632b90be8d458c6dcbe1f865f4b265ab27e2fc4bec75eee311261e3f52264014656094205b193315be6a3e5114663429e8823697d504b71fa9ad615acdd36625720ab40956501d998a3fe8037c7bb75032a4d53767b701ab3c150179bd50aa5553a4a272e48c71539d7da256e041ddd9a85b0a8d9dcdbcbdff94d80a4d8e5cefd292fe938f04cad77ba2ac86b57dc5660ee05f7220812ba6a70a2ca1cbc5f1736a5cf293f1acf96268df65e3e92362843d81337c88053aeed7ab2831b98f8494190eff3272d687c171af50468c49578a05a7be6c237460f93f9ab7553981761d483064233e7d4fad5104f5b001ac03ede1776ec0096ba323b765ea74a8c2d9a0d91e130ac9a4807dc6a8376fc362f4645d614d80f3f55e2cb49866a62ada62ae74d9288160bd5cc1d49b88a3326c5f447f9d47405a1b8b9eb23bd03c03e207c09cb59cd4dab8755d8d016bd198e45d1d5ec6017a61fed12b719970fda2a89874662a7e16ea11b185377c37977a1ed0af78fa3042dc17e192e4b3b2f7212964e36d357555d445348c2759d8e3bc1ba94d9e047ad8a40a05bae9f918187039bed17086ea457d1954d4c5575e9ca58040c129bc6fef20fe628d6d8eddead751729fa7d710802db77c1cdc47176512b098fc524024448230e4e95880fb5e375fa7f8300ff67b05861b605636aa04c167b4700b50656054c4ca323534921679aebb3be185412cd9ec0218046e224cd1b886d6a74d0e4479fe502d7038ea08a9a67da97eaf09e59046f6efa65348085d80d1832ed720eefc294365dad860b4afb412a0d7109e90f224cf87fc84338e15ad99e4d523651e0202aca201e98c9e440a4a07274c8dc95146a2e37a8841b6b6d48431f88373ecb7ff13b2c1c366aacf477e58a33af37c3ad1e8e708a10e5685878ce5db4074838b68907176239b6bfba643d88aac92bde285cf142952a135fce2308d9bcfcdb21955eb0342b6f9f18caf8b6f408c6c15cb976108097ba52ca2af509b489d379b27deb0470e6c40cd62021a74cedaae3dda546f6b86c1e5271d011d9145c55d407b359141d5cfeab5c820f221d199764fa369242efdae1210dd7e4cc66c3deb0ba8442bbd27c0e688415f2ddb961e72044b8846c911816b87384260dc81b717a5eed06724e8d5334008fcce70985b3c29166cd5f01e2901f44ce0f75ce0038d48353c2e7512bbc5acce012b90984d2558386a2a33a2e69a3c68e3daf841876a4a668f25cb061b1dc289c863b050351a0ddd787e3f9711d92e61037f180b0820adab8afd5a5fd2e7f198e6e1b9c8291012ef543585371128c62917167ba43a96aa42b296958753a91d16f5cba922d58cd8d2d1621922d
InNoiseSP = 2ed210c039786d1ec41d71737a4b8292d1686c60529403f5780d3292398c5da63f30ba6a67115432a95b5b59e1c981bc40b755ee043840591cde37a3b3ba8e0c82c297fbf569af43d5f2ac2c50aa0fce00d6f23a155a57c1ea9d6ad9649a23e482741ca773d07f52bde1dd9206fd41783e6849666cba022e6c3b84bed2060e0a57a38a255e7998c9d4c32d0d22980652ba2ca899eaaa69e28eb92cc0b6f9ea48725d1d41a86fea16bc12cd9b7efd5be446221b1b023570da87c3f2d2b49804c9f4abb5bae0823bb8cd066c492f1b64f1c95bc2202b3149d520478ef8f2dfcd4600d4c95481d99daba1fc389f8898a16d2e03fb7842e599c414162602e868c968ff3d06170f3eb845583f05e18d02be726e02051d25a9ac48856f7f33c1596c8f86a5ca98352f4c95ea0a13769398853878f62052eb8ebe57637610886331d5bfc4707d58f3f8b50dbc63c0f6d6213da93189b7c65c755a8a516ac9ec7d918aa53bc191ec6879c75273e31972f3d5d3652ec824be0490c2814abe918caa37e65e4c5dc42316e67d8638e6f2aae10a75c3adc9f2a92a11f4efc6262e1d609ae3a2e3358242f36d08d047911699ee00c319e22b7de9c9d1a0a40e78cf0bbbde864c6986cbf2fad8a50e429c794ff6a06b1f65b275523af0a14b4917f97ec51ac8d1a8da6cba92bef44a28b234dfd1160684461090c72790459247ef0d782331735a01c7194d6923d65be972a0d811900b3ef3000879c1eadbc3f06463772b822104bd32520ee9131efe630c2e40e06cae62b2c95204a4f0b3326bc6036cb53103402925da36a1ed822fd63dacb220e5f5f862ec123946a0a000612de19afe6361e52eeaecb4c40ec617344e3f4af8b16f3086347363b21ccb44b0cbdeae894f0a85b1cb6e68b6596ed29f418cb745a63ace6033a5a19d5479f4a3bacd9a7b39413dd4a21ac132b04d69e62ea8841963715c5e81705e35f496a712ca0a025dae4ad3d3a43b03acc6c0dee55b27936340211c9d55a43ab2acd6b47fad52fac08e3f7e5af0b1196062364cb730a79d097308551b8d4424fe1aa15b07f95afd076dca7430a95a0e2e8b2b78a1d254c184ef4d9a7fc2ab840476541aaf6d71d24e98d40d578675e004a18a9c2b40e1a85adc1da3f892911b887a8270f6beba60fc599f640cc7d3caf5589c8a0d911f6a35ac1492045c54fec2472f076f08c8ae15f9a684e0dfa98eae1d0112854601c92ef8805d112370c143a8a570a80b93a4d01c32ba416740a930042224d47ca0c058822c088d01c13287ab5bee6310fa17ee0a45053f99a7a3672d24a4594ce9a6db96bb0a9858d037d9b03db92417f728c1e58bc24829f1c73465fed9a49aaba0ba2e9606b6e2c16b23054a571c5565729d80793fd875f70074fa8dac536d67b491152d15790233d9fa4234d4cefffb52106ff65b965a857e0e3294962a35e4a782d5b67b6cce0876600b435176703f8f2b46417eaf41832dc6a3e4a481daa54224ea4e0c2894633d5493fa9f09d9a4ea40108644e0a6d434a6edbc07316e9ca2cf99a7dff61e39d93fd408940047626fc0b70082ac612d04db5c40805b5b176ab16f4f483f11aac0473ce84b79ee0db1049db25bbc047bd56fad872a0aaeb6ce3f894d02431b24f49b6255a99c865a3666287e74ddfb6a5e40111824f44b77ceacc1caab124390928da4abeab49198cacf408a6fb118609735a419f94589ca8ad1928907734eaf76e5e69a2ca75564530d7ac991a3a211f433ff9006daee25b0245943c394951786c37af063d0306a8d56e6ab862d0d0069f459904edbca539643a69ad0da4f9ab1906cabd2a22263bd41aba937f9fea83355ae32e3f49c7507c79775c4326a2715356b1b880c79dd0d58177839a21aa6a2fd726a318ab2c849c2004041e591a0c637abedea31f9e97958aaae0393c48934a94fd9d9c0ae6d871ee8c7e8b8a92c13862ee2a025dd668393fea8b6d09106d320bbf0889d73422c441cdfe66aa0127cce695b3a59da27dee407b837c47b52673142a4799ec8eae5607bf8bfdec37748793052abe594c51e0d67f424d013a640222604f8f1a2f97fe90a6a9897005d75452be1b940786013d61085b50de4819f36a3e80a93a162705f961e9e0e22b61b14164f06b9f3a9e23ae10e9648e1c92c70a92582b44d012e9d79ea7d067461a72103a0744766c2f1625ade67726d8e2927e8a8bfc56f20d9b83ae9d7aa121ac2439a424e2acd2233230936a3d7908d699582e3da922a0eafc0a3b8912d17ec1b043f4801bd0aa73789b263c3d9b5c3e08575c25642b38128927b8004746365ba536256f42b01bf58d661d0b8b0b3542b61f50b92782a8ddad8e9a4865dcefd08d7b43b0960ad5af436253fe7db64396d83481002c8dae47cf8a9a4196bb4a51f00e5c462059a7647229b548e5d04c06966956a0548189a6a0d59b1c05c80c6751976408bf4d649de7e60e909d11c1a8309e1c955a34d8beda46a47597c7ef9e3c965915c09c983d8d5c3e22f
InNoiseEP = d6d8b161e8b409512642cb760a3fd3d00d19e4067a48850e88533eb4c6489ac45bc0846650116500303bb19c96b2f8ea0f1f939fb26411bdb40a50654ebc5d4eac55d8b3dc5327eb5a642eed5761ac7695d02a1d266491d63e515518c1cbc400d2231e1d9163208a5c6ba32a471815aaee089ce4fe0c921125232908eea86059ea99e116b9261841e264a43aa2136dca03ad235d2ccf4095bc9ab1eaeea623e6af79db4ad67af97d73c34698ea1c0f13cd52d05c6a61eb284469f8b00af6c24ac6c5a4281ec9290895564a96d6f8bae1389cfccea802499c2e9e8be0cb50743c835b4e670fb82930c7fdf6e3da7d0e50ec0444d68dafd62571f1e4a2ddee6e8687b4b18228d3c21cf152f5e3b442cdd8afdbe31a7002f876c8e662f4682dafc5477f843fb44db1dae122e37945dd465b97ec41824364f79474b2bff2567a05a66eacc3ae13e333ea6889565189feca2050cb1f0abde21115dae186cd728b73e00452981a39a1e8aa04b0da22f26eb3cbb35c7959959558d6821d4b0a1ba426be7b6623646352947d5562fa4189caa8b812b5a89106274c0aaf02eae228969f946a2d1da600216058956d460366a9b6df6e223d59e0a30d22bbbc21d5427eb2b48dd367649b267330273e73b342551daed107bff228402033cac3fa0fa31e58ba56bd5725167e28852da5c58271dbee696785ed77a35f804e684ef452462d6444574362c99135fa59565b9dec543a25661121e49da42487aaa509b95d26eec71ffe4e4f0f578907fe6c40ecc862fc7e78ea5eb9366a5d1c0aa729da74e07b51dfe4ca54e03b04543f53a612012dda1ce517610b755d9f38d35ebce0cd89b7f2fc2386e5659be02a03e0195a05e1d222f2949fc95921bf211633d4de7c3f2ec7aa50df7592660a81b827b2030aead161ff29a34ea6df36ffaa5560d6a2e033226c30cbd2d776c9651dc42006ef140aa62fd37accc05cd307d2f64b3e0580a0df4b47751b3da41f7aec11219a9ea77baa3050d1aba37549704fbf6982bb294618c01f0953663157bea914ea6b0027642625a70ee6be3a899192378a1d9bd8e578b802237e558811f1a0610b5b0f6bbe3139f2defd8614a419b99597fbb38e0a088124d8f29c14661785888c5579ccd995461b1637cdd49ec49b700fc49671f37e985f72231255b62e78cd045b9b4d3c3d4ee294bad23194714b5f73dcf4a4d5612060301ea6b9931f81d8f5b4a32521fb0de6b9902b76f136796fd382d23163fc08e6e955e754a9b7816ac5172e5a41805d33732dbe910b862b6661bc72200c9a7b11821c65a90255077492a6d864aab89447016989a6ae4072084d4f438040237ea9d5b6f25152824f927afee5483a20750b994a3936a2466a05be166bc7a809cf88162e8eb1f22168a8262e36198a4519ba621b8787061564d013a07be92a74064b5bbf20a500a4eb4be5812b8d432d33a3d835630ae9d0d5f6a67c607b0aaf2d30ac6546e14f7e719ba2df78e7ca5ba25c4b6861be97349e7bc964860db41dba835a4403245b7b07c64d987698e8f02b999add2f0bfb42a244ea0f43e4c64cb5359478244f78a129c5c476abd5b36b6a82424bc07efa50e615f1cc65240c5c9216253f65c22042e1d1a7d4e657ca821c5f3da26a04ef0c96de9f60b9fafa56e19dfff8c43c173b12b8ab429e8dbdd3c4a978c89912d0ad98b6163604c52a6320d868391ec323e5c89d015e89e7a2a267f9168293d315a97a102a13c0a91e6f9d3f51925471ffdb0225c1f5b70094d211d9d27ef4d23e421bbaa1408aa478d4611a2d19f7e8b71e17d9aba5e39a2a620f6d7468ebca1b65488177590c3de42d8cb0dc3ca6d55eadd560158dbe53f380b805b34bd55d9255dc98ac204f470e06171e8a0a25c29c9eaba9719510dc8e2bc9026675060d4be392566b6c43ab83edf2dfc44cdf065963fa7cb11f152dabe87502e194ca241a4e823e110f53b1448f1fc09e204316bc8d4eb7559ea47806287ac463949d8a4dea242ed6495ac5b3aa85f2885d0d1935614a8d8c0d6cc8b93a7a3264741a0c8c3dcea7bba25c62678c80e46b52f97e2911b7056235138e20640217a6241097c598537e612b0fb6d8b7c665678e8c1b92f142d30b7e0b65cabbcee0d180dc02855f8ba9831612351bd84b76d9b89ebf4abdcaa5b9b7fe295fd6e5c8740e4ff713cfbd89d2a1adc8b9391ce76cd2a384aa35aaac6441fc522a47ae7cd9b11ea22ccc1efbd6853637448a04fed08be92fc748bcd98b1f8304a52756a7dfcd42f9a8426246def0bab7ee43dc238656904662695703265cc506b6d02568208c9ff5d006db90b48c9e22a53766717772ac05666d4927be969803418a8ffaaf76e799e069145f793ae4406d1bd7c8a7a9b11005ec0ab5fbc6ad4363b60aeeca0cac2ecf987dbc4222dd7f7398c573c166007b9f15bd90eeb195c40e72ecc62d274b389d2c188696bbcc9f26223fb68c448912ca34b1c43640f90f6a52173a9eba97e6a65a2d8f438815a5262e4f
InNoiseEPP = 00f0ff2b0000c0058000200000c0010000600000c00180000000fcbffc6f01f0fff6bf00b0ff0b000000ff2f000c000c00feafffebff02000070fffbfffebf000000200000000200011000fcbf0030000c0003c0003000b0ff12000100ff6b00ecbf00c00110000400007000b0fff6bffeaf000000070000300040001000014000e0fffabf004000e0fffebfff2f002c00fcbf00f0ff2b00fcbf02c0ff1b0000c002400110000c00fe2f00d0ff06000400000c00140006c0ff0b000300fe6f01400008000030003c000800ffefff1b00f8bf00b000c0ff0e00ffefff0b00f8bf010001100000000100001c000400ffafff2b0000c000300000000800ffef0000000b000400001c00fcbf0000010000fbbfff2f00acff02c00000fe0b001700fd2f01000003000000ffabff06000100004c0000c00140010000fcbf0040ff0b0003000100003c00040000000000000f0002c0ff1b00000003c0ff2b000000fcaf00c0ff120000f00050001800014001e0fffabf020001000003000100001c000800018000e0fffabffe2fffdbff0600fe6f0000000c000140010000f3bf030000f0ff1a000180ff0b000400007000e0ff1200028000f0ff02c00080ff3b00f8bf0070fffbff0a00fe2f003c00fcbf00f0ff1b00080001c000d0fff6bf02c0fe1b0000c0feef0000001300feaf00f0fff6bffe2fff2b000000ffefff2b0000c00100004000040000c0ff0b00ffbf0200004000040000c000e0ff0200fd2f00fcff0e00068000300000c00200001c000c00ffefff1b0018000600003000f8bffcaf000000f7bffc2f00fcfffebf02800000000c0001c0ff4b00ecbf04c0fffbff0200fe2f00c0fffebf00f000200000000400001c00fcbf0070ff4b00140000c0ff1b00140000b0ffbbff0600010000f0ff120000800000000b00034000700004000180003000f8bf0000ff5b00000000f0fefbff160000b0003000080000f0fd1b000c00ffafff0b00070001800100000400024000d0ff0e000200002c00f8bf01800000000c00028000e0ff120000f0fe2b0000c00740ffebffeebffcaf000000f8bf007000500000000040003000f8bfff6fff4b00fcbfff6ffffbff0a00feef00300004000180fffbff06000080002000f4bf03800000000800ff6f000000fcbffd6f0020001000018000f0ff06000100002c000c000000003c000800ff2f01200000c0007001e0ff02c003400090ff02c0fd2f003c00fcbf0500020000fbbfffaf00200008000300013000f0bf040000bcff1e00ff6fff0b00030004c0ff2b00040000700010000c00fe2f002000f0bf050001f0ff020000c0ff0b0003c00100010000f8bffd2f000000000005000170000400020000fcff0a00028001200000c006c0ffebff0600008000100000c0fe2f006c0000c0faaf0000002300fe2f00100008000180ff4b000800050001200008000080ff0b00f8bf00f0fe0b00f8bffcefffdbff02c0fd6fff1b00f4bf00c0000000f8bfffafff1b00fcbf040000e0ff1e00024000c0ffeebf01000040000c00030000000003c0fdef00100000c00880003000f8bffc2f0130000800ffaffffbff02c00400001c001000003000ecfffabf0240ff1b001400ff2f002000040002400020000c0000b0012000fcbf010000fcfffebf03800040000000feeffffbff0a00010001000000c00380ff0b000b0000b00120000400fcafffdbfffebfffaf0010000000ff2f001c000400030001e0fffabf0080010000ffbffeaf0010000400fe2f00dcff02000200003c00040003c0ff2b0000c0feefff0b0000c00180ff0b00070000c0fe0b00fcbffe2f02300000c000c0fffbff02c00200001c00040000c0000000f4bf038000400000c0fc2f00e0fff6bffe6f00d0fff6bf02c0fe0b00070002000050000800fc6f00d0ff0e000080fe2b00f4bf00000000000c00050000300000c00040010000f4bf014001100000c000c00010000000ff2f000000ffbf000001d0fffebf00000040001400020000f0ff0e000000ff0b00ffbf010000000007000280ff0b000b00fe6fff0b000700ff6f01f0fff6bf040001300000000200000c0003c000c0ff0b0007000780014000fcbf00c00010000400fe2f01f0ff0600ff6f0030000c00007000e0fffebf0040000000ffbf00400000000700ffefff1b00fcbf05c000f0ff0e000200000c00f7bf01c00010000000fc6f003000f4bffc2f001000f0bf0030010000030002800010000c00ff6f00000004000040001000e8bf01400000000000ffafff3b00000000b0004000f8bf00b001f0ff1200fc6f002000ecbf0000000c000000040000bcfff2bffa6f0040000800ff2f00300000000000003c001400008000f0ff120004400000000c00fdafff1b00e4bf030001200000c0ff2f010000fcbffeaf0130000800feef00000003c0028000b0ff02c0feef000000fcbf00b000f0ff0200034000000003c0010001400000c00700000c00fcbfff6f0030000c00
InRand = 7329c31474ae53402ff402d394b9567d25ab9fadeaca5a4f39805974ee711114
OutPK = 4a1de2132f661340403d82cb585b995cd9b1e55500474cafe43c0c0c30594a673d283cdcd7b427c52c99bb6a319256203072c8c9eb9582bcff2029566fbdbb390438f9570e9e0d41a8508a846ff9e4729530d58431dc3f183b04bdec9420898961a54dc20277b764bc3263e992e1649075e49fc62b793c74014aeb25cc26fa22d3c9e6c0902c1ec424425e9921113a0b11dc16e70c0c37c699a1fac49d846f8479f56ed2842a9c9feb290a238c99278a29becabb4d5241c3b496f00d7394ebb5c62caa4b6b68a4477426af6b59a0b55b2041a3a12a60f8c191354dc0abf24e4b1eabf82aa1941adfa450fb9e92af32681a679db4b5f281b76673725d9e596ab4cf8a448ec53148b5225a77d78d93b4ac748842db60cf80690fcb02da11559e17c34a79c3d94cf112f8e190782b4f9362172cee959e8c16c3e4c9492d5d304418c1bddd929bc557c89e5865e4550e0272912a5cd88a18108a2dead400c548761467371709a6ecc797b6cb383b8c530902d1618bccdde989ea75940b8ec3e5de652fa5274827d28048e5aa4b6ab1aa50d9e986331e927be94971cbed86868c5bcfd59b520f1347629224689bc583e7fb10642aa597c021022a4d954fdc10b312ab6267ae621de96ae42337e2e64c2d63141b58deac9f6f6f20e03c500ab647ce02f04c0779914dba1a4ca288d206986ae17715c37113ad727ed8ec887af2c58fb1c6079243106e3c957366b5595195e80e120e4d9debe9b2d9c52eafd66b1c422fa2932ce69f4890e004bec53968af64596d89b575035047e11f41515fbda8fd832b338b517b926b1187fedca03b8a9a724cd04288ef9661eb3a6c492dc5d16d94364260d28176214d494228e8929d069a10de59933c6bcba2de70beee7904a19da3c120675206d8347c912e79419754603159dd1cc34774157f7d0dfdb48114022b5903b993412759530ebafa0aaf1a0d2545f426abe3c1f5e949c54a722c05c200e0876f5d04da5b4d093da15d93587c88bb65a250c7da11aee77f5818a51381ea9a81b1fa4bb513f2c022e696b18ffb60c4ad3d9ca40ee745da79d6a880a932344a5e5372eb25059a7910d036104c1ff4956ba2358d5b17cee3076b11219fdb37f3fcdebc6353de299315516799b5b24f901de88d0fe113a6b21389f6c8eaea6a9f596c7b688961b418b5fa3782366c631d8b006905f618fc458ad87e6ac4a5b2f5ac28894828381f0aa26c0c21f148350cec11e5e39bde902584a2788f7e31941b7d52ce7e14e366c9772108adfa5f2823250e7fc965aab81162212d1ce245dfba74fbc67b7bcd821ec5984a75f5c9359348a333cb8586ca1c2a7a665c0aa6d29999b4b540a619251696a1bce815a287e2f801b36c8ce9bfb115bcd91efa22bd84a24752768e0937d1475361d8dd6aab55ceb4fbc5bff3d42ca85f955a5c9618faef90aac71db8c0d184b4422c96189124ba7fdad9c440bd2a966684fb84dc76c12db5570afda885ed7d09a35414c000e2323f0d588a8c4a40b46c679a24e8c32b5022bd2aacd4732e9f69a4e970c0e188d6141ff3892c698c6f33647dcc915088b9f43c4540a668e293a06e65b811e86b6ff466175295516bc2ac3dd0ab4350645d03aedac83e609125a1295ae7667c384a45ab77fa8700e739e5655253ad681258cc06b062117140afce9b4244860510755b9555326ba4be03568e509aff5001bf00370a06d6033e945669213443a34894d3f355a74a0cd551a918b837dab47608229b8f4f3ceb2ac478eda449a03744bb79077aaa875216888bb7c551ae06264c8d205aa5a1a76c7603b31a81e2e2cfa37c527ab3c534bbbae210812f6c1601b49174ed8a19159d72050c56900dfda35ae2baf78f8e0627c0fff839ec64ace027f2086d356084b8f3de9a59d26592425b096d38dd9044ae9ea2de966af0077e5add4289670c5aa16e9d9c61abc1abccd060440b363ea1cbc2f636ac4cffee0dd94d050a555bdb23f71199de9e44b90c351315495494d9266861427f80d87a966fc118151d659df787e9c5dcb6259fcd7381b7c906d5083b9149705644abe895b8005b2aa3ebc772562d8804050725cd60e54d5c56a79032edeb3d28c2c0bf1a5d765738299df565452527d5b8fb1804eb7ecd167ed57427fceeb426d6cb917acc4757da781098691304495f910bd52d356f61c9c9dc43c66e2429e6f57e1c632f4005448cbf95b74897e947abe126e0eaa6a40c559722d9a5b9b04f7be2a3a102a94e4961c69589a94684a1d155a02b8fdeb362882e75a71b9bf8fc2748c4e73852de28cd8726ca96b82c57d1e36225bd8ba44358536fba4b710bd8d4a9a9b2e1c99f26e62164794af4464df9584666aff8ee34b65d69a21028ac649657ee73c9550da69bbd4566399264465fa1b8358b8bcb92fb8978aa4a04df60b0bc5705c1e6e1851905cf1d70460a1d7e88d487a18ae1228f4278430b52127aea496afa4496e7628800dba95a1dc9f17b305ab82e19b593d9d6992264fe29d15157
OutRec = 01c00000000800038000100000000180001000080002c00010000400020000300000000340000000080003000010000c0002c0000000040000c00030000c0003000020000c0002800030000c00018000100000000100003000080001800000000c0002000030000400010000000008000300001000000000800020000c0002800030000c0001800020000c0003c00030000c000180001000000003400020000c00000000100004000000002000080002c00000000c00000000100000000100002000000000800010000c0003c00030000c0003400010000400038000200000000240003000000002c000200008000100002000040002c000200000000100000000080002c00020000c0002000010000c000240003000000003400010000000010000100008000380000000040001c0002000080003000000000c0000400010000c00038000100004000040001000000003c000100004000300000000040000400000000c0003c00020000c0002800010000800034000200004000300002000080001000010000c0001800020000c00014000000004000380000000080001c00010000800028000300000000180000000000002c00000000c0001400020000c00020000300008000080001000040001400020000000028000000000000000001000040003c00030000c0000800000000c00004000100000000280001000040002c00020000c0000c00000000c0000c0002000000003c000300008000000001000000000c0000000040002c00020000c0000400010000400010000100004000000001000040001400030000000024000300000000340001000000002400020000c00034000000004000340001000080001000010000800000000100004000280001000040002c000300004000180001000080000000030000c0002c000300008000280003000040002c0000000000002400000000c0000800020000c00008000300008000140000000040001000020000c00000000000000000140002000080001c000300004000340003000000001c0003000000002800000000c0002000010000c0003000020000c0003c000000000000180003000000002400000000c000040001000080003c00000000800004000000004000080003000080001c000100004000040001000000003c0000000080001c000000000000200003000040000c0003000040001000000000800008000300004000280001000040002c00010000c000380002000000001c0001000080003c00010000000000000200000000380003000080001000000000000014000000008000140003000080003000010000800008000300000000080001000080003c0002000040001c00000000c0000000000000c0002c000300004000180001000040003c00020000400034000100008000040000000000002000010000c0001400010000c0000400030000c00024000200004000100003000000001800000000c000240001000000000c0002000080001c0001000040002c000000008000000002000040003000020000400014000200000000180003000040000800000000c000380002000080000000000000c0002800010000c000280002000080003000030000c0001400010000000004000000004000340003000040000c00030000c000080003000000003800010000c00018000100008000300001000080000c000100000000040002000040003800010000c00008000200008000280000000000000c000200004000080001000000001400030000400000000000008000340002000040003800000000400010000200000000340002000040000c00000000c0001c00010000c0003c0003000080001000030000c000380002000000002800010000c000340003000080002800030000000010000200004000240001000040001000030000c00024000200000000140002000080003400030000c0001c00030000c0003c00000000000020000300004000380002000040000c000100008000280001000000001c0000000080001400000000c0001000010000c00014000300000000240000000000000c00000000800004000100008000100000000040000400020000c00018000300000000240002000040003800030000000034000000004000000002000040000400030000c0000c0003000080002c0001000040003c00030000c0000c000300008000040003000040001400010000c000180000000040000400030000c00004000300004000000003000080001c00010000c00018000000000000100002000080003c0003000000002c0000000040000400020000c00028000200000000380002000080000400000000c0003800030000c00034000000004000140000000080002000010000c000080002000000003c0001000040001800000000c00028000200004000140000000000000800020000400004000000004000240001000000001000000000c0002800000000c00
Key = 20eae83d111358edd1ef4c2dd731ec8ab172c5baabb832d8198b7f8f615a6939
InNoiseS = 819fc864be3149721adb2aafc882e380dcf06d756412c8a01283e20e6ac1a396c0e14228016352fab19a6b41009a054ebc5ad9a4dbb34014e1df2a7388be6d9593d71860109479801ea9c464ba476edb713664a3245822999c2d8490db2aa7874aaaaf4cc0a1a3fc4617ed5c86f25985078fe7d6f791984d55944621aa86fa6d07763f2e57122e50d89235b3a5ad9bc47684b5f1a0d9005b059b70038f319e31137bc116d7229cab130a331403eaa76aa2a5225b7c9e7f57470b029ebd8a402f55a83e10d6290c391cb90c549c1de65bf83ac64253674c2804701c5bb1e616bc806b72224d8d1c43e049ca146cae42c75569c6797073dcde9028345ce38021a535daa7288018e56b16406a4e8869bbc656070e2699625d14ba996e81431a2d0a14e2405a082e40e13fa2b37a1ecf9a3923a68e1d990b812a1ffe9a674df40029747d846ffc894238b9279901c21489b975aa670448a4766a484918ed7551f9ee7a66bc26b88b002c7bd8f51f9b8c42a8e3ba214815bd687648459f10f2a391856ec3c5bc1a358980b1aea10ab26e430663ecc38018323f2c36daafaa1ce252774913ac30b6d27564c5c20e11e74606b1c1075ba60e451756591d443ec60ce49398d7b4ba3dd000630aab95b8111652e0c110fc04059a68a5c17c5e0a8382f3a32de475f01082a2fe62264b6841a44da669475348dbfda93a9304c502abf4b1710a5b27cc39a8f0e705a4633c5fc65951e4c7f86525c0d760079a75aa587a32ff0e9b82ccfb324a7e8abe9eadb940e10da2ce00f82362b26e8447a1eba21643c0b0e02a2d1190ef51db4a5969aa5c50d2bbe64d8fce2186f2647dff4aea76b78d33fbdf7d74bfca0cb20125eb5a74b1b26d68e3531db09f634bd134603438492df7c4d1a7402f7559e0a4ac8b8e0c417569478eae95226a747d7ead94390c5633041b27559d1e27bfe9104209897e3700edeba72d6f496cd87b7d446a1569b490dd8abadea4096b67396ec8c269bbb7f264bc9d9af9423829a149c3433b215528a90bb1a44878a2c84a35e23220eace1072dbb03c7c1f6059da627e9ca408c572b03ba1ee726739d8b32229f4ebc87c9b7fddff1652a24d02868c50f7cca61da9fdcabf6e733a1d90fa49d66fe8e73d80b0b6a567ace5b62b4e12cf1c5e738199881795ceabe2a517ab2009a90999ac002a40147ec93511e5b484b38213b09200549e1e386b9aad924605721498c0c2105a5129c0877aefdc25319380735eaa680a97c0b51abca6605a9af4d9167e87cb14a6c7424b4d427fe4db4e5fe9867004833a159069a3f6592c232a4e2db38512bee2a9b991d415352b26d83115e92d6567e0d943c67f8ae7b694c1e6beb1e857267311310426713a842e46aec68c0b4e9825a3133273c76475804aed47f31c36f8eba860a600967953152372cc1cdf893e325ec92d14ca45a9135a9c5b5cab4413fdac9f90cbd74be6beeacb6b248d328f081efbe6f268672cc244c04fd6509f2df12628b4a1c9e614eb1c6157d8981e9a6a019e2cd745733765582e92a518b2785056c7e932fc860f162c4c62e738baef86e588e3155515e0fedb0bcd997094d93b122d7d54c01296704e38b4ee47d0b67d5cc784f95a3b845969c1cf9ae3364a314f8aab0a19279c1784f6dfdc77c4e65fe5f43a77a8cabed319cd69ce96ebe04b254465da81e561103b242a2ca971927371d985327b850c998965327d18273f66c4f98281070e940ddbe46e8a4dac8130c4690b561f7193b3518cc464f096e720097dab1a17b4d4bb2ad6abf84b39246f470fe4589410a52888c6c00163d16df7c2225ea8071b9154a0fa340a29cc4bae8a37640c86f9ee7ebb1fda52040b09979a85a1b09f5432c884296191167e1802949857d1490c862ebaf40104a9cd22425338a27de46c08e34299090679fb115d473947831052dd883805d70625944e1723de9217857ab05aa2f70461982527d7d07db403b960800991fa06d7299a77447043eacdb52036082403867f0a182031179cedf1de9d0a5da71782718d6c874dd359be309f7090a94835e10f732c9dc9dff59abe1ed8441680117811f2d909d53a29a26bf47756444424f548e89abebaa25652e10c6373127e489d0d2123e278d05c842ac99ec321b6ed6af94eafc6216a54f62f00e0dfdd44b40eaf85cbed5819c0e553537182b1d9f9548c0e08845ffe8aa53631f76814d759a55fc9d020d2148415b61634864e6e590f5fec73cbca732c1fd19329d90e7821dd106515442d4698b957f697b2c9fb652826283287a064ae861c9c96c58261c20c51d642c5e0e09e84288dc2fd16550787a8d6b1929adfeb1b2392854977ade19af270825f9a20c6c2c5685b08b4f7c27123494a0365bdf50d8acc29f53afe2ee3a743c0b19d7d6613a39a19a20884d98086a5ae633e1a150a2fe2ad5853614b3ce94fbe401be3223d260a5a6994c321366e6daeb06f166989acf825aede985d4ab7b1948d81f7eb27e946948f5dec13765bd203
InPK = 4a1de2132f661340403d82cb585b995cd9b1e55500474cafe43c0c0c30594a673d283cdcd7b427c52c99bb6a319256203072c8c9eb9582bcff2029566fbdbb390438f9570e9e0d41a8508a846ff9e4729530d58431dc3f183b04bdec9420898961a54dc20277b764bc3263e992e1649075e49fc62b793c74014aeb25cc26fa22d3c9e6c0902c1ec424425e9921113a0b11dc16e70c0c37c699a1fac49d846f8479f56ed2842a9c9feb290a238c99278a29becabb4d5241c3b496f00d7394ebb5c62caa4b6b68a4477426af6b59a0b55b2041a3a12a60f8c191354dc0abf24e4b1eabf82aa1941adfa450fb9e92af32681a679db4b5f281b76673725d9e596ab4cf8a448ec53148b5225a77d78d93b4ac748842db60cf80690fcb02da11559e17c34a79c3d94cf112f8e190782b4f9362172cee959e8c16c3e4c9492d5d304418c1bddd929bc557c89e5865e4550e0272912a5cd88a18108a2dead400c548761467371709a6ecc797b6cb383b8c530902d1618bccdde989ea75940b8ec3e5de652fa5274827d28048e5aa4b6ab1aa50d9e986331e927be94971cbed86868c5bcfd59b520f1347629224689bc583e7fb10642aa597c021022a4d954fdc10b312ab6267ae621de96ae42337e2e64c2d63141b58deac9f6f6f20e03c500ab647ce02f04c0779914dba1a4ca288d206986ae17715c37113ad727ed8ec887af2c58fb1c6079243106e3c957366b5595195e80e120e4d9debe9b2d9c52eafd66b1c422fa2932ce69f4890e004bec53968af64596d89b575035047e11f41515fbda8fd832b338b517b926b1187fedca03b8a9a724cd04288ef9661eb3a6c492dc5d16d94364260d28176214d494228e8929d069a10de59933c6bcba2de70beee7904a19da3c120675206d8347c912e79419754603159dd1cc34774157f7d0dfdb48114022b5903b993412759530ebafa0aaf1a0d2545f426abe3c1f5e949c54a722c05c200e0876f5d04da5b4d093da15d93587c88bb65a250c7da11aee77f5818a51381ea9a81b1fa4bb513f2c022e696b18ffb60c4ad3d9ca40ee745da79d6a880a932344a5e5372eb25059a7910d036104c1ff4956ba2358d5b17cee3076b11219fdb37f3fcdebc6353de299315516799b5b24f901de88d0fe113a6b21389f6c8eaea6a9f596c7b688961b418b5fa3782366c631d8b006905f618fc458ad87e6ac4a5b2f5ac28894828381f0aa26c0c21f148350cec11e5e39bde902584a2788f7e31941b7d52ce7e14e366c9772108adfa5f2823250e7fc965aab81162212d1ce245dfba74fbc67b7bcd821ec5984a75f5c9359348a333cb8586ca1c2a7a665c0aa6d29999b4b540a619251696a1bce815a287e2f801b36c8ce9bfb115bcd91efa22bd84a24752768e0937d1475361d8dd6aab55ceb4fbc5bff3d42ca85f955a5c9618faef90aac71db8c0d184b4422c96189124ba7fdad9c440bd2a966684fb84dc76c12db5570afda885ed7d09a35414c000e2323f0d588a8c4a40b46c679a24e8c32b5022bd2aacd4732e9f69a4e970c0e188d6141ff3892c698c6f33647dcc915088b9f43c4540a668e293a06e65b811e86b6ff466175295516bc2ac3dd0ab4350645d03aedac83e609125a1295ae7667c384a45ab77fa8700e739e5655253ad681258cc06b062117140afce9b4244860510755b9555326ba4be03568e509aff5001bf00370a06d6033e945669213443a34894d3f355a74a0cd551a918b837dab47608229b8f4f3ceb2ac478eda449a03744bb79077aaa875216888bb7c551ae06264c8d205aa5a1a76c7603b31a81e2e2cfa37c527ab3c534bbbae210812f6c1601b49174ed8a19159d72050c56900dfda35ae2baf78f8e0627c0fff839ec64ace027f2086d356084b8f3de9a59d26592425b096d38dd9044ae9ea2de966af0077e5add4289670c5aa16e9d9c61abc1abccd060440b363ea1cbc2f636ac4cffee0dd94d050a555bdb23f71199de9e44b90c351315495494d9266861427f80d87a966fc118151d659df787e9c5dcb6259fcd7381b7c906d5083b9149705644abe895b8005b2aa3ebc772562d8804050725cd60e54d5c56a79032edeb3d28c2c0bf1a5d765738299df565452527d5b8fb1804eb7ecd167ed57427fceeb426d6cb917acc4757da781098691304495f910bd52d356f61c9c9dc43c66e2429e6f57e1c632f4005448cbf95b74897e947abe126e0eaa6a40c559722d9a5b9b04f7be2a3a102a94e4961c69589a94684a1d155a02b8fdeb362882e75a71b9bf8fc2748c4e73852de28cd8726ca96b82c57d1e36225bd8ba44358536fba4b710bd8d4a9a9b2e1c99f26e62164794af4464df9584666aff8ee34b65d69a21028ac649657ee73c9550da69bbd4566399264465fa1b8358b8bcb92fb8978aa4a04df60b0bc5705c1e6e1851905cf1d70460a1d7e88d487a18ae1228f4278430b52127aea496afa4496e7628800dba95a1dc9f17b305ab82e19b593d9d6992264fe29d15157
InRec = 01c00000000800038000100000000180001000080002c00010000400020000300000000340000000080003000010000c0002c0000000040000c00030000c0003000020000c0002800030000c00018000100000000100003000080001800000000c0002000030000400010000000008000300001000000000800020000c0002800030000c0001800020000c0003c00030000c000180001000000003400020000c00000000100004000000002000080002c00000000c00000000100000000100002000000000800010000c0003c00030000c0003400010000400038000200000000240003000000002c000200008000100002000040002c000200000000100000000080002c00020000c0002000010000c000240003000000003400010000000010000100008000380000000040001c0002000080003000000000c0000400010000c00038000100004000040001000000003c000100004000300000000040000400000000c0003c00020000c0002800010000800034000200004000300002000080001000010000c0001800020000c00014000000004000380000000080001c00010000800028000300000000180000000000002c00000000c0001400020000c00020000300008000080001000040001400020000000028000000000000000001000040003c00030000c0000800000000c00004000100000000280001000040002c00020000c0000c00000000c0000c0002000000003c000300008000000001000000000c0000000040002c00020000c0000400010000400010000100004000000001000040001400030000000024000300000000340001000000002400020000c00034000000004000340001000080001000010000800000000100004000280001000040002c000300004000180001000080000000030000c0002c000300008000280003000040002c0000000000002400000000c0000800020000c00008000300008000140000000040001000020000c00000000000000000140002000080001c000300004000340003000000001c0003000000002800000000c0002000010000c0003000020000c0003c000000000000180003000000002400000000c000040001000080003c00000000800004000000004000080003000080001c000100004000040001000000003c0000000080001c000000000000200003000040000c0003000040001000000000800008000300004000280001000040002c00010000c000380002000000001c0001000080003c00010000000000000200000000380003000080001000000000000014000000008000140003000080003000010000800008000300000000080001000080003c0002000040001c00000000c0000000000000c0002c000300004000180001000040003c00020000400034000100008000040000000000002000010000c0001400010000c0000400030000c00024000200004000100003000000001800000000c000240001000000000c0002000080001c0001000040002c000000008000000002000040003000020000400014000200000000180003000040000800000000c000380002000080000000000000c0002800010000c000280002000080003000030000c0001400010000000004000000004000340003000040000c00030000c000080003000000003800010000c00018000100008000300001000080000c000100000000040002000040003800010000c00008000200008000280000000000000c000200004000080001000000001400030000400000000000008000340002000040003800000000400010000200000000340002000040000c00000000c0001c00010000c0003c0003000080001000030000c000380002000000002800010000c000340003000080002800030000000010000200004000240001000040001000030000c00024000200000000140002000080003400030000c0001c00030000c0003c00000000000020000300004000380002000040000c000100008000280001000000001c0000000080001400000000c0001000010000c00014000300000000240000000000000c00000000800004000100008000100000000040000400020000c00018000300000000240002000040003800030000000034000000004000000002000040000400030000c0000c0003000080002c0001000040003c00030000c0000c000300008000040003000040001400010000c000180000000040000400030000c00004000300004000000003000080001c00010000c00018000000000000100002000080003c0003000000002c0000000040000400020000c00028000200000000380002000080000400000000c0003800030000c00034000000004000140000000080002000010000c000080002000000003c0001000040001800000000c00028000200004000140000000000000800020000400004000000004000240001000000001000000000c0002800000000c00
Key = 20eae83d111358edd1ef4c2dd731ec8ab172c5baabb832d8198b7f8f615a6939
InRandA = 312dee62b48992a86afc71cfed062c85e5f76ce279f42a4e0561540685c1cf72fcde7f4720ef87581496c59d3cf0d14a745aa1f23292c56ca380c12045b184669164c73c3a2492af440a78453a1012fca13d290be6122cb832ba9de59019b8d0a40b6e2a8a99483931b5ee2b4971256cc31107c2cb14503e079d27570e37ac03c2aabce21990c0e4693c2a4c0eeded78361503d9023fd60edc742463daa39d32826ba8eb136dc02e6fcad62aaec67d9392a958ee094ba90b53b78c7496941644a04e7654ef51d18b66c80d4b55d9c3d5153760e8cb8495182e0a8ce50327142e286c27303ce56edaa6f74683cd8d10ef12d9970c30352574c06bde230f00d089214c6ad913333430a903f5253f13fcc4249b50efd5f0ad0c7b450713f84190e722c8b368b044744ee5c04172719d48a2919d3815c0c47a04848011c5843ea755007b9458a7c82340a243045d017946651ed32172980e353495df914ad64c2ad4ba925e4abd2b2fddb544386e4dd65feae8e2b0ccd0a2d2742c8666266762b4b6713b17240b5776278a6e1ad4c2d42ed64d32b14cbc66e7cc8844510a30faa9bfc179566034865ff0f7fc5510ca31e3093d39ca23c5c5d2e4b5b61b1c41be690b3822f6624cc99c2754710893f01105682c8685c11e36536114f07261e1e6a659f7e25c59824af93030a773450567a6c5a7f0150c7331cd4f60566c13a2320f2bcf6536e6b16ede24c3cb69f451de672451367969a6dd6d0afa58afc7daa9b6fc450d802ba879fc22207289783a79e614d3cd4f6ab0652a6a17bbb7f9659d4f14241a08382a549f4ac102ad0f8d8dd9706f0db4efa9c2dbbb9885b4e961289961ba8b8887d0b9dd20f5101e0890012d39a9e115c87a255001287b08b29ed9989b670b802e485813155bf1398c0b0409be7c1cba4b0a388014bf5bd5218199e63afc8d5a1548342fa14fa0e135ac7e05a5b9e1c475b6e7e30c1a75d630c05b43125b75410d055744f35805232183d57915a0e6a28eba865c61201baeb03cac68fb23fe6090f67f80cdb5039bc45638afa0a36520ac20c9ebd3a0d55d3c46d0ca48e52de52bbe70c3c911fceaf6b96a2e748a69b9d94bde44d5d5fda738226d3768a5d96a0e20b112af01ff59bbdf9c9bbbcea6af9ac22b74c2721222c07842296c5a1de44053eea0870b94ec94a1b0b1710e3dabfa3aab9c49ac1b3e019b712c8da748b1859b2aa5590ec4a7e78f1f1461f4b23015a5a9f5dd2e2624be2098580cf8de4b470a799a7e6c8753bb02b10c1dc1e70bc26e9c6d89039d282a8edd20274b5dbee6184327249664742e733a6d7d7e01100b638408b3d0479e80980d58c026a347fad6733de51b013f983455e257215adc3761624288cbfe8cda20459104bd18958415f2c120704cae55d2ff9637fb599835745869c127a4522e1e26fa0eb8f04c8a6cce41b09be1b1965c05a6551f74530986b6d7adfc53ff80bbb018b56e66665df1b0455b25d34c18b4b5b616051af4ca559010da68b8fdc6bf998b39f0def85c9fd9db86960d9ac5d99ae685bd2686546b6391c08426dfdeb133de4939689c67c569a2f7958ae70d31b5620db92963e0af8e2c25377258aee1051c9adc749a0d1e87d1b1bc0c9a5c13468b408172832cd893e025076b77d5a496b1776053fbac2a8251c5773632b91c7505bcabb57605ae2280e30b94131b63fca8caa8b6ed8477e60cb5005c48d91952b25caf5c2c8743be2e6754b712c0710d4f9f94317fa24a411271f8b4e8669241d6ba9cf65b7493fba1adcd0b4faaaca6bb2d8d79cb4e233d704a6725e5a4f19e1f498a96e783817b470140c0a25551650cd88ae4fd330b4212f6d848ae902ff662573a0ca7a6cc63898a6eaccfb97613456309e32e800fa039735a486962c9a58493afb7b9dc0c4bd9b12bff7e767b8f6f42f7bd53d0837a7574ddafd04cde42234a4919981cfb6d8841a3c063e03a52bf8598b0f12d6a28f82a4177a5ee7c3c2af1f0675685f8ab3c41cdec3046081b268f7999d9a17555826aa6052b8357d0b68b606a1d503d6627bbe608a4ccf94851502946390448779e9ffbc99a8d66874e988774b508ee66a03c5c94ca6224a618caa1ad9e69091ca4aaf840b856e2c1742a0ef0b067eca80849e7145ea574c093a12736bd207a51f51379bcb2ac2f08532e5097b6e0455516b0aa27c2af52f406b3f29cdaa7cc9609becf1821dd9c9839221b86f01c6c1c93169bc0fc6f0864adf9cfd1966e00cd52fad9a9f522ca821a2a2dab40fab8e199aaac12e2f1154032a49c5ea7a4ec2341051714136ab7e5193de862f12005881933b4601603daf7056e2c8582ce56b2a9aca49b5f3411cb182fd85f5e586bbc8124cac764eefe16242de424d5f89d1f5ace352829554c6cf10b488c5e7513dcf4a2685c904dc0727b040d14e7d92115ec256b590ff1a9b2295d4e7be92638b21fd55d8ad23165318d844b252523fca19961b9d60cd76597541ca04dd310080127a2ab8145fe9a8ba5a4
InNoiseS = c1e9a276ceae5b944e79f8c57ab825a58ba9d01a23cedd5b2b2172a3f8ac35e80b5a3f84c034e226219e78e800453f3ab95329bfe0f4c17246ab6193db9dbe324b5f07f0998d6d83d24208d1b51298b5166c66258d26d86278843e3ddd13da7ebe0ed24902765149465113fee9461a84af1a68c8bf76769603e82a21a693fb0442bb70f599d8982076b9fc36a42c46b75db8b1699544e557fe21330ee6b53bd2310e6dee459b7a6fb55cd640ab1881334542aa920a8ac4e77c87c60ab1c98ae888f42134db67a7b809c69fc81194c487f24b61a011b086d058cb4556b582c54e4f047f50531416539ea7c1f04e7db95bacd3afb616812285354344167ee4745512601dfdae2a9afaf531b40e16d86569420b2805722ad890ed17308035c8943a0daad4e8c8325e8cd7d0263803879ebf420df2b761a86939b4e19ab161ae22bc045acd0af1985dca8230a752150191b20890d0788b9e8e299d08fbd7664e9645c43940c1b06d1c8251cf859d158fb5b515e40c0aaccd90b370020383b71298cdb335803d4b58fd3c8217435218b6b970d180a284d17b7f61ebeb9a46b8bc476bf321010f06128c02e171763dcd10b655aa2542213b6467800f134284da21622f6c20c522d1d05adf9bed5b7a6d63a3ab7236074e1f9b999138ac258900eeaf68a8328ed5084a23cf7cbd851ba7c222d1975363a0770cc446e7c4ef51e49457eaab2ef1fce02a1629c68b12d1aaa3a9bf041a765030d0e2a719ca712fec479ae3f5a4c2caba024ddc2c4c2c354bfb5c55b62daccb7a068adb03253437f87438643ee9d86929d5681b52b87664ace83a2672daae7c1f6c6aa2c486f9e3bb31c4f27b32d047a6af990e08d36e3a8fadb376cecf67989c4977d33d56db106107de6e89849646132a23858514a8931ebd4383d2635f90b2f17b7d92eae259e6ab4da034992a1b6ff215254e78a930fa6cf12283b7d23c73e08788a645b55268ca37e6c49227bb5f2f536caeab9344b7904519509990616250f127201bf5631ec28f5b9b7897870282b69bb46a8854bb5a66f626f9b5a394e062e4208c194cd1b963747216d8975f28a2480dc04a0f31462287d463ab14969827aa2f4fc4c30e977153e9e992688c8ad0b5c3efd17a4b95ec910881311649e223dd8d9348e11f0183560b345a4064c1205d4d41fa5b2b5c60e00dfdb2f31199d8897ea960fd78e6000b7bbb94720d275d9bbc819ca124dcf706a27615209cea60b952fb90455a2bbe3d311b9da08798491684a6291e915aa80b1983d6190610a094173575a7772587408338571e8e248a0b255c18a2cf4684040d215f88da53e9a6114903c3683d3eed814de857742e76a95282d87877289abbe54efdbc9d1961b1176cb5066d3f0bf7556be86106d1d6e9a8bfa8d5fbecf460095821989abd55b60261c8287a137feaedb0515e45694721081851957e88d105db0d974d5d5cd5a9386a8a037f315abe3b809b7f1b6656ac2d269452a39868e66b8e49543584f0667614a9f0aef09a7d956370a6a58353b70196498924bfa073ad687b1ee1a768ecabb7ab15f22fbc71579f7463429d69670d2ec605119f319574e572ee229f6241fab912addb1b83d71bd143149408abb1c15bde84ef93e6d2693c9423d99128832629e6d75b682e0e0181a0dcf442b4c27c32846431a3a6d8690f1c188a9a4274bf284bf12bf0a0dc9672d358b1b6243a631fdefa6464f9463c89f7e423ce03fcd5dd22fd606372296b024baa86c8c922071842a5084a799392ad39880a8b50d9386c7d60f3920db18c1feceda8d72e36e3db48858c00b0e921e35a09e1b16bc54428e0f119b7cd07466af576ec1908f489206e8fcb16580a8271d612ef272f8a5e18c947e10ff2263b08e46527b42d1c993774ed4139ccc0b39566adbacdd1aacb0eb2aceb6dacaa2cb1818b53e8e4b2995ddbc4f399f86d80e6644a2550d129f0a21e84f8950aed8cdd59fd1d09470ea43a19ca7f6a8de69422f0b3078a87a3129a8d819478a470d0624593620182087f57c62450c5f1121486c377648c3e5118e59659c56fd408dee705beae9b412467884904c1488cea3fc51696471ef154f9547ee6ee4636ae578f0611b4311c83e744f186ce2013e8eb00633a3a9223e39ea9107a13639a4dc0457116d20899da92e623b64240d090460a43d88476564c630f99a049f5ce5e34d645c8890e71099f16ebc72121aa044685fdf187e166155736bc1429c85cab2c808c0a1eda3bfbcc737395b4845031807b872407381212efa6856b69b145db0c4fa936ad6f05a824c10f500ad9e91cca8b7c0d57e38c3b82a8bc6d8132b6ae16381604ebfbfd8e8416177ca560e2983963fb1b25ae28d85071d251493e4c27a34319f04eb387a592e62c95b7e8b426dffe2b6d2ca89a71e091bb15c542ad9cb4211cd789b95c13972b9aea65e12051af44020f52971e61324245e9154d528879e559644ec8f7470e06a6d897cb84a13a656ecd55a69dad7234c79da3450a4d
InNoiseE = b123f788afbd9623d25ab427c24266da1a3104cead00810400d2c49d3a0ccdd384345791ac7f18527ea9968bcf80a5ecbc5b9830a46989995409b4c674442c820498c56acd262fcd76487e79186163bea2d9fd39a90f8d067da930e8ae17ab53cab136acf4c052613794e58c9b2d2d2cd087bca67714a6958189da4be411241d22b59fe2a571982203dda53ae4a19684ff5a6f461b5df8065d8fc10ccfc58c5a82b194e67663ed26dcebe96960287e2345a102d9712a1688f915e59e84608471cabc182963d809636669bf58ce70867c8d093ee4681416ca1daeacee7996aa15c8e5e4980621241354e8d6424a6cc42720683b509fb5a26566b1d17cd6c02367cfd67348128973544429c48a77f842f93eb9c2ea51ab5e0adde93a3abfdabae3dc6b73fa20a21b9e5984945621a49b0ba465f279b440c0c43f3252656d300429429c859aacd889127c880fe62167ba2afda491f25fac8cd09ae3c540c802b366be5787a264dbdc5608ca5863d5a964a39f58b5f84d122af9d11a8e63a2a5da74b205e7827baa9c23c9d6428117be6ebc6a204bd1243c406de5962e3c40a2561cfb612e45584d8d3b51a84e13d57ba4cba4077912f35654b62f5acd9c40368e12a45d14f661bab0aa1b03d547a430cf92b69424a4202e092f943e1d88b60d4f04c3345c6bec4cb1f3959d3d4041354bf492d318ebd3cbe4b6d02efd49d16e2c47a988233f39731fd68e8964758223a0e86829b1307b2b0828090849a5037b73cc49558ecebc25881d4dae4dca4967d81c7c623871315d0347ec9d9a74e2864a0542e4930036f487c8d980d043611dfe2b5e554678d1dcb75e3e489c6f6192275ca935d04c0af8a48e17cf6dd807d9a0df204889c2cc71e291d0b2db7dbe978729fb9130455bd91144405c8c7b006a69a258a0dc9bdfa20824b1665778896d41816e90348b88e811ee1e001692624f3d27ed5115545bb80928413a4a1dcb0d00e92ea29b55c7a2b4801a54776d63422650039044ef7baeee3bce2cbca65928252415e3f131e17d0625e155315144195c48f0317c22346595a360cc8f8be07f492e1e3a31e066074f3170a4e954f5af0672db877f1726d9b3e304b85ad81a80715b7272f13d9bbe2b1055535578ed19bd32327e9a9659d317b129545c8f2d1600da2cb4a5fc73452c839297695b211d52a021c5b283c97d4443f2523df1252fde96b1007467fec8a6157dc6426ee63fb8a56239cdc202a18c591fec875c39f98081d7ed08466344a48b244f40836eadaf219bb7f81ab67459a7189568047d811938feb0542cde5333b932ba2cdef78ada3d36cd10b2b553c025f4ae3e07ac82042cabdeea9fa69a0ad6048b6c113e2317808278f29d679ecb0b6bbd5a84e8f94b059a0a510a389add6e3f97d49a38646041802a13757bc69f16916d320f258d81ecb0484fb46098d2b64b171e418388fea898349d29d4e3452ff2a273810d24ae118d3de6364b3dea83d4a124340be5be610af4351f38acc2073880fea0705ae68c550a7488dc8de10be321987c47fd36949c8dc20603b73ed20699da946a5449b9220be249c9c1609bceea464fa834d9565bd7f9cd1b95e349978a8aa727a03f74778698164d9e537c04aae48333a0265563b1a7c8e3ec3043d5277fc79fa876d6c464c4d17e7d745cfd20f3786c65e546eb74565984aaff0550427a074bafc6bc583806a2eb5acb151deeca2c35a8fa2efaefda17f5242df2c2f6a4baf16b2d689995ce7896ec93c0f81901a0789ca76814b49c8d56d846546472984603d521924841def323a36c1c0d23f551151124c40c1cd964481888aca737640128cc9b6feb821855cf1392b5ad0071fe6389386ded227eeb8f4af27a2fa6128fc4c0a9578484182830d97594ca8b856c3c860d9896383649aceb8240aa500dbf1b540d0820a232d4e86b676ecd59b94993452b1e20152385784af462b806434398262ee884d4dbaf1c5f9e5404d13f9c5a5e83ffb39eb26a5414cab5f479653bc916d95b49b5d8a621e95a588246052602da45a080d3f928c4c4820d455a31673924dcced89af2a4bc2a815621fc4d9500eaf499d2f42ee7938a28dfd8089acc467bcd104a93a097b211a4767f9846a75cecac405e35228efd3ecb0ed72a85cd3607832f4b5c6e8d7b97319afa1836eca366343a896439de14d3ce3e2f0740e3bb79e9ab275e2b7523f6528d0ae6d22185ad89a61d5541ee33940e3e9ae556891f09090a22f4bdb303dea398bc99790a1333555d9a50aabde3b9e6238200b8254a8eb8c2920711a04978508615a3a6803b5ae4125890fa1ddb2e7ada364a05dfc13d645f8d8c7aed656a62c4a1f0804bc4405c2cbb5ff068d0e4979f232508a6166deea5c10149567b3b8b0ceb967d002ed3deb381c68a8d0fe71ad4301fb815c2a5c9f46f0ddca0d8f20205b38aa1b0fd32b0f6e91ed8f4b0b6ae5f02523772599e50f1f770aca9705cb563600863a81f4f74073ca4374cc89737f2601e0214e143920a
OutPK = 535792f6599d034f5ed9e9b5c5b3c10110f32ec45aad4ad1315f9268a65f8b97d6f1b2d4200711378574d62e6c9b71b16ad3d5b70bbe4a8f538646973f5c076028a0e7386962f49059e3dc20bc724f4ad20eb9402a5d1df57c09762ecc2804a9fe11c42f085a174c2f0dc98be0bea24e3e20b1f88df0545f59bee80282b166861a43ca8273a6013f760fb2bef65c37789b1aaf02220dc155d153884a40359e511e9c23a6f2434916190a11fa75320d6945af461a921ed2ea3068cacc33822147e9b8cc59f4c958483039a50d145d5b7974136255185478587528697cc20f989a2912c6324ad4273690b34baee43c26dfcf01dcbc4dab41407bf246942dd41d1926b24150aad8892b58116895ef53bf281088439c8947189d00879e931192379b9633a1235452fa283718f692a7f566272575be6076a995ca80149841abbc43d7941d810b07687b0e1e9e6d2d439c1d1c8a47f486a41a2443e7d95962224af6562c23e6e5533c2a82009d241424daff48325aab87867924d0ed1b57166934afdaa52296ab097aa2181328f88995b4095519f7545518add8610e0aa5ad32776986fab0a9b83cd860f054318b1de8e366df454bc26d8672dc89b4aa268066067e2727469d32463253f0aae277bead7f9d1090d215e6b3a116268617766b75263c4ab6ec010918e566696a93dd2267d30321897e8507fb348511276df33497726bb4c1d4d38f0049a5cf4cb5841c61e96dec029218579b100539be5216891914606f1a97cfabc284167e8ccf1acde59d0c61542085a6ec490913500e488a389940a376d1d799b4332e470a44190ea2a435770feca6bb46ded13790206fccedca4192a77948eee594ce6e064f49f5e7bd85baa272a67db9a68a5d9b44ee0495fb434579bb9a2c6be16c79d1545b85226b469bb857e2115317bdc91c0c2333c1e7000f476c522685b52d98dacf7325241900f08ac60aa225f52ee134978617c78d68726d76ad7e27b7776c1827674d267a1f0551f503ee960b3e3a7aa19af0640e3cdc1381f74542a13b6629d337c2980f40ba664461a982c5e736ba4d841c248ec345b05f9b46669a44043903453f03dda48e236d6714bd4e7fa89912d991a1696e40bd82fc0669b7d883840d624a74ed7fd7d6b57a549c231a2a4c1fd5aad98699607be149d65244644656d93f0173c02f53cd1c79b62e80ecd82cf5774a69e05ae0ea7a1c02352d499821894e9286d4077af49e9441acfad4b21465dc0dd359b07fc4617cc316e1a4954b55542bf07d818efec0ea15abbd04e2e90230ac6f6dde24084238cdc56649f1209f0ea0e3611c2abf8d45710184f4a54a22202652ae4a5ee9f720b4a023fe4493c6d22971b693f0fb9a194a8c9a41789b1d7fd020faa3c936a91de323d0290c84ff978695b09643512f6205a1e1150d842521718c0544812a6855ba63cfe15cb2bfb16dd9aaa54b1ce8302f568062c14122d767082afaad9c3d85ad148e969a1b0ed8d19516427f297ab8eb1e719e81a2b6e6da0148a933e830fd16650c66a3b2d57b4c0269504c11121c4ad1a0c839b8650416850deda33fa31d35d7442fdac994daef5127b3eab1a1587034a5ebe7911ec46139ef3b4b8c8a9889ed2412172d3c8a163f413d1dadf51c3e60df100cfd2474730cc63aa221b863b2a2271b8b1109610d417f489ecbeed2362385c127625c0d50a0ebc3fda5a5d1e645e890924dd38044eb645887795a02b6b0ac48fe813f17a47c7b53e58d15176110fc9b16b503f297b4dc6b28fe1148e96ffbd408e41489d201c590b2285c0309832a3e22a7441c70501857f1ca0744a0e20910683bf023b6397485246600f161d927d0d9c34d7bfa59fc7326b450edd9ba45b621a3ce9315914c798d96a98d55544051536cf082674e13ea14d8b028bdbe99451d0774cc85354afa87f3648d36c9b8a657bd595e2ea80061b6a9059baf41a652961265aa42882d926fcd4b91860a229ec22561d596b26950976b08719ced1e8469536d43f9a8a69998ae4ebe435739b811474b1c48721bae7aa36d40655a9ea69a1a5894033953f0d6e488d1d62133a9c309c3d49e8c4cae0acba512519d11a0997e81215cf55ac0ccaa055d6deb039c672ea8ec81b34a175b45c9448d45a1479c84d95031216c0b8f30cc286859daff9a6a8e4d836d5ea33cc030532de579560846311e7b496a501bec2de3ba760d3f0e609659f4109f0fc1f6c70df56eb6122bc08082784748f375fa9859bb2b6207a9550bea67af4bbd141a5e591ea83d392af2675575ba4e19636bf6c1670a813414d08b5fc989e49d8840ecba24a6d192d63a11bb6167a610f786a769039c83d99d9f0fc6fa89ee21a475c7960918fe5e70dea2da3c5985aa63f6889886a4b8631eab5910b9f0578ac94c919a5c42167435be09c487e496465213bb5e9db5d8658abc2a6416c68e873a8a3e224c9c18bea9b8c983c53654e5df65e065205721dc199cc442440b6727b610822cc9f4d044511e7fd673f168cd26
InPK = 535792f6599d034f5ed9e9b5c5b3c10110f32ec45aad4ad1315f9268a65f8b97d6f1b2d4200711378574d62e6c9b71b16ad3d5b70bbe4a8f538646973f5c076028a0e7386962f49059e3dc20bc724f4ad20eb9402a5d1df57c09762ecc2804a9fe11c42f085a174c2f0dc98be0bea24e3e20b1f88df0545f59bee80282b166861a43ca8273a6013f760fb2bef65c37789b1aaf02220dc155d153884a40359e511e9c23a6f2434916190a11fa75320d6945af461a921ed2ea3068cacc33822147e9b8cc59f4c958483039a50d145d5b7974136255185478587528697cc20f989a2912c6324ad4273690b34baee43c26dfcf01dcbc4dab41407bf246942dd41d1926b24150aad8892b58116895ef53bf281088439c8947189d00879e931192379b9633a1235452fa283718f692a7f566272575be6076a995ca80149841abbc43d7941d810b07687b0e1e9e6d2d439c1d1c8a47f486a41a2443e7d95962224af6562c23e6e5533c2a82009d241424daff48325aab87867924d0ed1b57166934afdaa52296ab097aa2181328f88995b4095519f7545518add8610e0aa5ad32776986fab0a9b83cd860f054318b1de8e366df454bc26d8672dc89b4aa268066067e2727469d32463253f0aae277bead7f9d1090d215e6b3a116268617766b75263c4ab6ec010918e566696a93dd2267d30321897e8507fb348511276df33497726bb4c1d4d38f0049a5cf4cb5841c61e96dec029218579b100539be5216891914606f1a97cfabc284167e8ccf1acde59d0c61542085a6ec490913500e488a389940a376d1d799b4332e470a44190ea2a435770feca6bb46ded13790206fccedca4192a77948eee594ce6e064f49f5e7bd85baa272a67db9a68a5d9b44ee0495fb434579bb9a2c6be16c79d1545b85226b469bb857e2115317bdc91c0c2333c1e7000f476c522685b52d98dacf7325241900f08ac60aa225f52ee134978617c78d68726d76ad7e27b7776c1827674d267a1f0551f503ee960b3e3a7aa19af0640e3cdc1381f74542a13b6629d337c2980f40ba664461a982c5e736ba4d841c248ec345b05f9b46669a44043903453f03dda48e236d6714bd4e7fa89912d991a1696e40bd82fc0669b7d883840d624a74ed7fd7d6b57a549c231a2a4c1fd5aad98699607be149d65244644656d93f0173c02f53cd1c79b62e80ecd82cf5774a69e05ae0ea7a1c02352d499821894e9286d4077af49e9441acfad4b21465dc0dd359b07fc4617cc316e1a4954b55542bf07d818efec0ea15abbd04e2e90230ac6f6dde24084238cdc56649f1209f0ea0e3611c2abf8d45710184f4a54a22202652ae4a5ee9f720b4a023fe4493c6d22971b693f0fb9a194a8c9a41789b1d7fd020faa3c936a91de323d0290c84ff978695b09643512f6205a1e1150d842521718c0544812a6855ba63cfe15cb2bfb16dd9aaa54b1ce8302f568062c14122d767082afaad9c3d85ad148e969a1b0ed8d19516427f297ab8eb1e719e81a2b6e6da0148a933e830fd16650c66a3b2d57b4c0269504c11121c4ad1a0c839b8650416850deda33fa31d35d7442fdac994daef5127b3eab1a1587034a5ebe7911ec46139ef3b4b8c8a9889ed2412172d3c8a163f413d1dadf51c3e60df100cfd2474730cc63aa221b863b2a2271b8b1109610d417f489ecbeed2362385c127625c0d50a0ebc3fda5a5d1e645e890924dd38044eb645887795a02b6b0ac48fe813f17a47c7b53e58d15176110fc9b16b503f297b4dc6b28fe1148e96ffbd408e41489d201c590b2285c0309832a3e22a7441c70501857f1ca0744a0e20910683bf023b6397485246600f161d927d0d9c34d7bfa59fc7326b450edd9ba45b621a3ce9315914c798d96a98d55544051536cf082674e13ea14d8b028bdbe99451d0774cc85354afa87f3648d36c9b8a657bd595e2ea80061b6a9059baf41a652961265aa42882d926fcd4b91860a229ec22561d596b26950976b08719ced1e8469536d43f9a8a69998ae4ebe435739b811474b1c48721bae7aa36d40655a9ea69a1a5894033953f0d6e488d1d62133a9c309c3d49e8c4cae0acba512519d11a0997e81215cf55ac0ccaa055d6deb039c672ea8ec81b34a175b45c9448d45a1479c84d95031216c0b8f30cc286859daff9a6a8e4d836d5ea33cc030532de579560846311e7b496a501bec2de3ba760d3f0e609659f4109f0fc1f6c70df56eb6122bc08082784748f375fa9859bb2b6207a9550bea67af4bbd141a5e591ea83d392af2675575ba4e19636bf6c1670a813414d08b5fc989e49d8840ecba24a6d192d63a11bb6167a610f786a769039c83d99d9f0fc6fa89ee21a475c7960918fe5e70dea2da3c5985aa63f6889886a4b8631eab5910b9f0578ac94c919a5c42167435be09c487e496465213bb5e9db5d8658abc2a6416c68e873a8a3e224c9c18bea9b8c983c53654e5df65e065205721dc199cc442440b6727b610822cc9f4d044511e7fd673f168cd26
InA = 312dee62b48992a86afc71cfed062c85e5f76ce279f42a4e0561540685c1cf72fcde7f4720ef87581496c59d3cf0d14a745aa1f23292c56ca380c12045b184669164c73c3a2492af440a78453a1012fca13d290be6122cb832ba9de59019b8d0a40b6e2a8a99483931b5ee2b4971256cc31107c2cb14503e079d27570e37ac03c2aabce21990c0e4693c2a4c0eeded78361503d9023fd60edc742463daa39d32826ba8eb136dc02e6fcad62aaec67d9392a958ee094ba90b53b78c7496941644a04e7654ef51d18b66c80d4b55d9c3d5153760e8cb8495182e0a8ce50327142e286c27303ce56edaa6f74683cd8d10ef12d9970c30352574c06bde230f00d089214c6ad913333430a903f5253f13fcc4249b50efd5f0ad0c7b450713f84190e722c8b368b044744ee5c04172719d48a2919d3815c0c47a04848011c5843ea755007b9458a7c82340a243045d017946651ed32172980e353495df914ad64c2ad4ba925e4abd2b2fddb544386e4dd65feae8e2b0ccd0a2d2742c8666266762b4b6713b17240b5776278a6e1ad4c2d42ed64d32b14cbc66e7cc8844510a30faa9bfc179566034865ff0f7fc5510ca31e3093d39ca23c5c5d2e4b5b61b1c41be690b3822f6624cc99c2754710893f01105682c8685c11e36536114f07261e1e6a659f7e25c59824af93030a773450567a6c5a7f0150c7331cd4f60566c13a2320f2bcf6536e6b16ede24c3cb69f451de672451367969a6dd6d0afa58afc7daa9b6fc450d802ba879fc22207289783a79e614d3cd4f6ab0652a6a17bbb7f9659d4f14241a08382a549f4ac102ad0f8d8dd9706f0db4efa9c2dbbb9885b4e961289961ba8b8887d0b9dd20f5101e0890012d39a9e115c87a255001287b08b29ed9989b670b802e485813155bf1398c0b0409be7c1cba4b0a388014bf5bd5218199e63afc8d5a1548342fa14fa0e135ac7e05a5b9e1c475b6e7e30c1a75d630c05b43125b75410d055744f35805232183d57915a0e6a28eba865c61201baeb03cac68fb23fe6090f67f80cdb5039bc45638afa0a36520ac20c9ebd3a0d55d3c46d0ca48e52de52bbe70c3c911fceaf6b96a2e748a69b9d94bde44d5d5fda738226d3768a5d96a0e20b112af01ff59bbdf9c9bbbcea6af9ac22b74c2721222c07842296c5a1de44053eea0870b94ec94a1b0b1710e3dabfa3aab9c49ac1b3e019b712c8da748b1859b2aa5590ec4a7e78f1f1461f4b23015a5a9f5dd2e2624be2098580cf8de4b470a799a7e6c8753bb02b10c1dc1e70bc26e9c6d89039d282a8edd20274b5dbee6184327249664742e733a6d7d7e01100b638408b3d0479e80980d58c026a347fad6733de51b013f983455e257215adc3761624288cbfe8cda20459104bd18958415f2c120704cae55d2ff9637fb599835745869c127a4522e1e26fa0eb8f04c8a6cce41b09be1b1965c05a6551f74530986b6d7adfc53ff80bbb018b56e66665df1b0455b25d34c18b4b5b616051af4ca559010da68b8fdc6bf998b39f0def85c9fd9db86960d9ac5d99ae685bd2686546b6391c08426dfdeb133de4939689c67c569a2f7958ae70d31b5620db92963e0af8e2c25377258aee1051c9adc749a0d1e87d1b1bc0c9a5c13468b408172832cd893e025076b77d5a496b1776053fbac2a8251c5773632b91c7505bcabb57605ae2280e30b94131b63fca8caa8b6ed8477e60cb5005c48d91952b25caf5c2c8743be2e6754b712c0710d4f9f94317fa24a411271f8b4e8669241d6ba9cf65b7493fba1adcd0b4faaaca6bb2d8d79cb4e233d704a6725e5a4f19e1f498a96e783817b470140c0a25551650cd88ae4fd330b4212f6d848ae902ff662573a0ca7a6cc63898a6eaccfb97613456309e32e800fa039735a486962c9a58493afb7b9dc0c4bd9b12bff7e767b8f6f42f7bd53d0837a7574ddafd04cde42234a4919981cfb6d8841a3c063e03a52bf8598b0f12d6a28f82a4177a5ee7c3c2af1f0675685f8ab3c41cdec3046081b268f7999d9a17555826aa6052b8357d0b68b606a1d503d6627bbe608a4ccf94851502946390448779e9ffbc99a8d66874e988774b508ee66a03c5c94ca6224a618caa1ad9e69091ca4aaf840b856e2c1742a0ef0b067eca80849e7145ea574c093a12736bd207a51f51379bcb2ac2f08532e5097b6e0455516b0aa27c2af52f406b3f29cdaa7cc9609becf1821dd9c9839221b86f01c6c1c93169bc0fc6f0864adf9cfd1966e00cd52fad9a9f522ca821a2a2dab40fab8e199aaac12e2f1154032a49c5ea7a4ec2341051714136ab7e5193de862f12005881933b4601603daf7056e2c8582ce56b2a9aca49b5f3411cb182fd85f5e586bbc8124cac764eefe16242de424d5f89d1f5ace352829554c6cf10b488c5e7513dcf4a2685c904dc0727b040d14e7d92115ec256b590ff1a9b2295d4e7be92638b21fd55d8ad23165318d844b252523fca19961b9d60cd76597541ca04dd310080127a2ab8145fe9a8ba5a4
InNoiseSP = c64a30f40c2146684b38004f9863741b2214bf060817d2d629f93e74cbc804336cc16adedf04d06e9d15a08426d15811a0a649cdd63ec59b4cafb7713b793d3c06f35b70a516eb932cb0086ebde5c3d7ab1f9017a10a0c382d3a7add8ea8195fc1436da06591293178f58ec70abb2e967ea9b6da0488995f593608c815a48c9c26b8035a33496efde470043b6cecb9f1c1c4b1eca56d572a382fe34df759cd15aa0465aa29e16e9fa71e673784662d534152db401db62bd0762864e84f392da410da063ca169646429fa5f361798e26fde806c9f268879669791adee4721d071b1ef4f7a6f64508e44e1b47e2c3bf0c12f77b4350cb2cd1f96d76415af453d016bbd638aafa1606d8e58eec8e1a0de86b466d6f7b7cf469d1d6e1847bc5c6874d78bd9b14a630be4c6db7b8529ef8fd18832084491635ad6c97e55b9a60bf0a4ea4899017481dd39a3420269417c71a520d7a2b3458d4f4e4a63777b14bb84ab31f2561c14005466c58a9e9a588d96c252e17d8e82cb3509d406c151f0521d9d774ad166675801a54ca6f0993dd12cf15f44d20da8b9fb052265bcc6524ac95221377834348cca46a23804874b12f9641418f6454b4612ecb7ab1ea664e4047fec42b2790cc6903b1205c8ab668a3596b3838ee958996f09d4be74ae0a18ae68ebf99c2d51df8ac3789cd2ee2521bbce27b4c718a6a4a210c124e54898d9ab04295e11e7ed01bb5b4d12cd9e341e0293b539a8ba619924db875d1f30959499d70186af9b64922099989596ea22f9399a0da0c2b049913bba52836a0b9cb0e6a0b225bcfd2c808e9292082977b7ecdca3b556bb354eaa2ab2a5bec6cd1d029b561789d28c523eea3822ab1f6468beb9b06878bb7ca69ebcc5e0c4ce9831ed2ed4e6ef4c01812e20054966b06a93e5896c2a054e14c90761793b3b8ea562dffd99a71b6854283833b590b5f03d7ca3f25534684491091e17dff72c9174474f4ad26ace5e51a5f78308716878d1ee07bf441f172b3472ec324cdda53bd04ac00faecac6a012a97a6fa22817ca217517e2b6c9dc74245a6a0b76260d4bfcc5d4a2de267815968c580d5dbeb2ad5ca39c0e979c184d39cac65cff1860f589c895bdde0dfbf45450361bfac39d8208df9d87f476c966d8daa8da7d1a5ff25a00d3a771706cce66a2e0e827fc9c55c2f442a831012df93b3035a51a4371049155cf154a96f5546d65c14e0136483bbfddfcc1aa2928b71010830a60191f9808840c3c894cefc2755ada5ce0a3dbb34eee0a0725979259425ac7678d834296039201cc4786ee974fa49497931461c95fbccb07555d0e60184664344992da6d42c9253c176deb548996a41be23e7a03e04badcbebf70dc6231a176aabb310438e25c379f4796d9d038cf7f8ac99aae2abc5639abd3f038e722465b8e45f01a2587534de24fa77d2b1ac5d882346a4422ae3211fb0f751a25c92393524619bbb014eb1564a245be8fbc55eed48356004e56d396f2f55a9daf9e0a35da47f23b7940caa0d2e26d4d68d88c3dc7a180637726da7336ea68fa4e5a8c124342c93e825a47419bc47e43b747e8c45558fba94e8ac0b5a0a5b51bc667b114c94064fb192b7182ab46908916a233fc959903e065b4e14991224c1a31424a18a0445e5c1ebad02ae87a88b72800d694c6bc940df3574f7501893835298b842c4d2b31063d91a1399e08a66a6886b59ba426f022d2317f5b298cd1dc1b1df3d8d4bcca913754a4b1946b39156357add4143948ac49c8644779b5ab1b7036193b7788d9c2ba55d74fe8d46c4840d7b328574320942f5f3e5150feb3079ce2c7abe5923e62c217e6f4e1f36b5796838c617e75f7921cb9a0043cfbd4da225f6f45492ba7f85dd51c62695f94bfee8d674b32b81de685530b7bde2825b000c3e2a8eb1f44c1a52cf23cea72fd517f36f4e587dde8161093f7801693e71e9f1d757f8532499a414a96aa16ac8b1409bad18205ec0646c5546b4047b06382101c521ba414d6c3b5f81c3b2c1898fe22538222cf825ce50a8b3dbad37e04db1f538d1701061ed41ba593acbcd3ee198442b5f1966914930129c8196e5cc422183ed2726b6fcba19c8d285ff0ab0908261d713856e12a5c198f9b2913fecfe95a0a4b4c5125eb87d640514961b5720582fa4d6ef87ee653a805570b4a326a6c2c2a46398fea5ed1e1fca0c857799de7a4b2258846adcae3282417e936bda359cd4893e118b363379125d13de48764a8cc2ae391745b263c0d55978900a7ff39902c5f6f85a8a254858dc529f4c6e2451ccbd140e82e9ab60f045efa83a12390e62060e920bb30eb09c289325597e0a819da13a0a555bdd8491599975a12c9f2aa7ffc660b75a2a0735749467ea7475131da2488427db46725242819dbb7bda96acef61c1367c62254f4868eb0d6de1082d70370849764b3bc02035af46dfa474791a82ca87e433d62174b6dca59532a59d0560d6b0779e7e3be36d9ad9723abd0e9bf8e9d56914e50140d8de2c
InNoiseEP = 1084eda5639e2a95dd2c094281973c88e05852785c2d8e11822d4e257b8299449f751d69d084fac98c6a216e028ba52dba4015ead204e893ebd62d323cde8580a99f05b56676a441b1d636fe553143cc573e1855f24c667a9d8433efa38af3e0de544743e69769880796e95e6006919ef5ac9c9bb7d416719b2ad80de0812e11e3d3c541976e1f405662f27aa11707b8a858bee897caa5e0d06d9d92ca099c75a747e4dda9340a8b2c8d63ab767279e7669e7b66ca2718851bf0adc494906799c5b25e744c06c74445feb2e8ae88161079b46bec4cd920de6fc59de5d2d3f96f8463b4ba77ec7eb32fb3b0b1903661072bdb6018aeffa56125b09016e89a40817e38607eaa801191a493cf0e96207972a24561bdb40c3da2d78903957ff268f0e9dc3a3f3486fca5075a7cb832b2a08919e9366f1d4b2761a63dbec44fc5b5aed5b0742773e58d1a7cdb044204883d31b3a1d8634ab26f53846f7372587afbe4cf471fec7068e574e89d9c2e6ce65217d0cc6fe6620d1601e5b762d36a54eb6612d7ad663bad406111d2cc3618dd891d42ca66fe3944f38812392bbe8b9086e4f259be81b7953756532d741a51087377a8044013760a72806b108c055173dea0dd813f8a70349b9fad63b44f20a3b0418f4548316fd26cc740b6e9b324930b252822267b656fc1882ea0856301971d1a7e3fd1630a9590b96d16e7c71e1d808d00ab899f780809a612c2fa152fc4497e50622c37d69447c6ccfd0d355a10778cd1b88894c9d47ac12ac7a4b311d359863caef86aea8d7416576f161fd92bab081cb8e06d1d198d6e9b0895583a651a229b250778dc049710542594c79c45f338861e679cc554e6be3c2740a8733655e6c5aa5b8bae797f5b442a58599f321ae316e592bc380b879a87483eeb9d9761a550ae9ad46940056582d11ddd6870108b16a4d53b11896c6ce60ce1415e3f3c082a6a10413b354250b0d97561d4a0b9f36588137555c21824440b2f928aa6e3403a9061fa4b53cc73dda4cfa867449d5c65a090b16a87500df94b4a08882e11910bc51ea7fd06eda4a7a66640c6ca915ca89ee5cf322b57412d8c4d8d3385ad147241ea978f4282acc3dd10f3ba036be51646a3c63f3c578380b6687a816fd0c2dba86d9e8ba79940cc0b7c49e1034681227cddedf2ee6e638549141af0744d7d817730ea98aae4d0bdea72fa9506511714c64574da0e3221b1ee52d4deadd3bd9934752fb0c3a4f148f64f21a2815131b842ddb6680c49c21ae3a7c9dc4e5c405b8964728d67499fe48665ab7993b91a972e543699e7336dca6a889a8a3636a86cc7df9ef9234a1855629a01f592a6b8c6509bff789f2c446f81ae591b8458b5089f10984fdd8bbbf46259b91009174b4a8d2ee32fe1c190360d91d251638661b4c7e8ea623e6a2ac138f1aa8d9a2a2c5c87d83a972d4b36133b69416e8af142a5a612f0d7b80138b9750ddf813b7ac8204ad789bad2e166a5e3560589c14e9389a6932c743fbfc78cc047ca3a06da436baf8c0a651dcb74e356b9e9e7b7e3d92c88ab0920e54dae161491d1907159b7bad30e16db74547e061f3b732a819ec9d565cd769e915c8802a59528f05e2d70a04d991b6af9d4df6c122b6ffa15c62db8f6eedc120f7232a2e03a1b1442a67da1d6463af40d1ca8b2e2ccc5845c530036a6085b7f2969162c58aec6ed2ec71334583f93c47043e94c34d2cb2640f5b0884f1bc3ae9e2658e9d40b18c89540542c877e7252daebbdcb1c8d0c5ee5eb6ab46a3efa8ec02877362f562190614c65893a0240185ab1445727e5b400ed996184f0076a155134242de6923095fc65812a548d57de2882483c194f8a92d765d51119ac195ce56b785865c3837806f516c5566c5a32e5493e6da2f7959c7f8e2ca03a5b46b488629e463436956f2381f938a0311dc4950b3b56164598b2d71b1515492630449465bc888dc14b7bbe7e3cce4fa2f0861d52633f3689f068f19645525c4c09b01af422d95c9b480e1f0a08691ad98d29940a22260296e85436e47f891eb2f27261050464c7c1603c904b59c268c98490b42f4b7992c952d316c14a76928b6c0d3a19a93427ab6f8f503bc087bc4bc8227990378ec9a4c8bda8282f4aac76572519802d89e606a031209bec03b242ae73a6a1c839e513b50415d9684e58eb44e90a7c7957f4accdf87fe46ebf45eb12e8665395a5e357ae64284c841ec664bd9b1f2f9f53594d96bfa367e47fe6338804c6e03409aae54c9a3032702bb50fb3039bce16b0d00f1a6d747dd74d17054f2923f8e43316006c3b82e4b3b003b551ba534f1a8a45bdbf1729813f2005812edf29df358f629047ab933dafe59f998a854421621fcdc10726309122843347a07671c91f048dcd1d0b2369988ddc13616064838be1852765ec9a145a2dd6247afa521a42ef885cbb0e226fd84f8693d0f836daec92c75486a8434d9cc40436b9866c90600e000e3ade202446c145866931a138e66d96cd25a256219b
InNoiseEPP = 00c0ff2b00fcbffe2f001c00fcbf00c00010000000040000200000c0fc6f0030000800ff2f002c00080000c00040000c000080001000fcbf04800030000800fdaf000000fcbf00b0ff1b00fcbf094000e0ff0a00030001000000c00580ff0b000000ff6fffdbff16000180ff0b00130002c0ff0b00f8bf00c0ffcbff0a00fe6f00b0ff1200fdefffebff02c0faefff1b0000000400fffbfffebffc2f00f0ff060001c0ff2b00fcbf0440013000fcbfffeffffbfff6bffd2fff1b00f8bffe2f002c000400040000acfffabfffafff1b00040000c0ff6b00f8bf0200002c0004000300002000f8bf0080000000efbffdafff1b000000ff6f001000000000f0fffbff06000580ff2b00fcbf0400ff2b00f4bf0400000c00ffbf0180ff0b0023000380005000fcbf030000e0ff02c00040001000f8bf0780ff2b000800fd2f002c00fcbf03c0004000fcbfff6f00f0fffebf0380ffdbff120000b0000000fcbf00f00010000c00fc6fff1b00f8bf00b0010000070000f000e0ff02c002c000200000c00030009cfffabf024000f0ff02c0030000000007000200002000040004800010001000040000e0ff02c00030ff0b00fbbf0080ffcbff02c00180ffcbff160003c0000000070001c0ff0b00f8bf0140ffdbfffebf010000f0ff02c0ff2f004c00fcbf044001b0ff0e0001c0001000f8bffbaf0010000400000000f0fffabf007000e0fffebf00f0005000f8bf04c0ff0b000c00fc2f00000010000480ff4b000c00feaf000000f7bf007001000004000030001c0008000600ffebff0e000000000c001700fe2f01000003c0fd2f01f0ff0e00ffefff1b00f0bfff2f00fcfff2bffcaf0020000c00feefff0b00e8bf0380ff2b000000fd6f00d0fff6bf0440ffdbff060003c0febbff0200ff2f002000f0bf0280ff1b0010000000ff3b00f0bf0030ff2b000400007000f0fffabffe6f0020000400feaf000000ffbf03400040001000fdefff7b00000000f0ff1b0000c000c000f0ff0600feaf0000000000ffaf0060000000ff2f00ecfff6bf0200001000f8bf00300000001300fd6fff0b00f0bffaaffffbff0200fc2f0110000800034000d0fff6bf0030000c00100000000010000c00010000dcff1a00fc2f000c00f8bfff2f00300008000500001c000800020000f0ff02c00070000000140000b0ffebff0600010000f0ff060000f0ff0b000700fe6fff0b0000000100003000f8bf01400020001000fd2f00dcff0600ff6f00400008000480000000f3bf0400003c0000c001c0000000070000300000000300ff6f01100000c008c0fffbff020001000000000f00054000c0ff02c0020000000003c00040ff0b00fbbf01c0003000f8bff82fff1b00fcbffd6f004000fcbf0100000c000b00ffef001000f8bf02400030000000fe2f000c00f8bf030000e0fffebf04c0ff1b0020000240ff0b000b00fdeffffbfff6bf07c0ff4b0018000180ff1b00fcbf00f0ff0b0003c000f0feebfffebfff6f0130000800058000100008000640fffbff1600fe6f010000efbf014000000008000000000000fcbf007000e0ff02c000f0fe0b00000005c0ff0b000000003000100008000100ff0b0003c0fe6f01c0fffabffb2f00ecff0a00030001d0ff0a00ffefff1b00f8bffd2f00ccff06000000001c000800ffafffabff0600010000acfffebf0300000000f3bf00b0ff2b00f4bf007000e0ff02c0014000f0ff0a00010000fcff0a00030000ecfffebf00800000000f0002400100001000feefff1b00080000b0fe0b00fcbf00700010000c00ff2f00f0ff160003400020001000ff2f00e0ff0e000030002c00f8bf0280ff3b000000020001c0ff160000b00000000700feefff6b0000c0018000f0ff1200feef01300000c0003000dcfffebf0100000c000400010000f0ff02c00000004c00fcbffe2fff0b0000c0feaf0100000800010000000010000080ff4b00f0bf007000f0ff0a000040fe3b00080000c000f0ff0a00038000f0ff0a00fb2f00c0ff1600fd2f003c0000c000000000000b00ffaf003000e4bf02c0ff4b00f8bffcefff0b000300060000fcff02c0feefff0b00000000f0002000ecbf034000f0ff02c00080ffebfffebf00b001d0fffebf054000000003c0ff6ffffbfffabffeefffdbff1600fc2f0000000c000000002c000c00fb6fff3b00080002800020000800004000f0ff02c0018000e0ff160001c00000000400000000acff0e0000f0ffcbff02000030002000100002c0000000070002800040000400fdef0010000400ff2f000c00fcbffc2f0030000400fd6f000000040003400040000000034000f0ff0e0004800010000c0001c0000000f4bf030000ecff02c000300110000000fe2f00e0ff06000680fe5b00f8bf0380001000f8bfffeffffbff0a000000001c001000010000000003c00100002000fcbf02400000001300fd2f00100000c000c0ff0b00f8bf0000ff0b00f0bffd2f0010000800fc2f01c0ff0200
InRand = dcc79ac886c7ea2fb60721ed2c18a72a4684f1a2668c8bab4b7cd6de29e9834c
OutPK = d2d75576a45915b2cfd75b4bf06b375114e4f74011e94172661f6644abce4f161ea0558ea13e358eb55f624a6191b25c6ae818f358443078ae43df8a800024254fd9191219b3ee6e2cea5fac0e0a0a5b8aff580b69972b592c311b65ea283267803a7407a663685e87419482505288759406c311ff79b69fd50923ba10120fd14849689471f3d74e74fbb17dd8a7c6e3315147b4d2b6e10b1d8e5fe5c0f9af15b7c80d2d165779a2ec26518bc9d8400def4707f2d8598e56f20501729f3fedd5fb136dba0e5539670a89906e9fab0327cd647d5a9c80e9dd5501469123deb9654d477b297cc4b4efa0f39aada4a37b54b94715a53f3b4bb2f2af109627504db876f505d020fa2103ee81862992a3be24b14749f52017460e83adf847a049108eca92294d117b1e6a146829a5b5699b73312d228a5808e1b11ff174484cf9920f20a016cb8aa461ad41ee13ada4f26d223d8e0678205a079e0de22b51a1265b86c015ab1132c19de6fb09650cb1a33f14eed944291b4629133a3c156e7bf85dfc0887a753a72a5930e8890bfb59fc1d5fe926fb30be72d520c8b6a5908cb5da4df7a34135b3862cb85c1162202dcea8a0a843ea441004d0d4a7ee90372174ba8a680b0137ec4887f44898e3c0a22e3696c33a7a76980b8f5c45ea126d769c6a337574384927e5c17090bf8a506edb6b60be7a9a7b5a32851aab83b2c4d8a66a44636261a6f0b5e72830c2edcc38069039701d58aa0f4730385f449cb3069e52b38d55f2d7ac981bfa15af4bad04200964b8e8aee47a7420f8e428ba9a5005ba89b323a8501fa3a5b0332895a865c408b24c7e8d8ae0f710880dbad5d0920bf676a1340c7e77b1fd2e890f3aa492ae2c2662bdb451f09e17623353d37eb0cd20a7c96abe0ffb2ffc42f88171374580e27b64a550ca636aed8e12758de313d2f22a6c6feec89dca4bd0cd69a5cb588b0a9f6d61a67d9ffd062627aba0653f5a5025385423a51bc5570afd0d88d196b2a8855ce606d2d5227cb1182a90b224ee39f52f5aa9d6b685210ec6db683caeaeddee41c30c26304464855b7562898482a361f4567d53c703559850d9436480c9d2923f1c4264721893798fe950b8dea6466eb51a045943faa88cf31c1e4dcac6a741ebad731a604ea3e04c558dcdbb82d361a1de843b59587c593f0c12a5b7c4acc325c41a8cc9271ba5d6763de51c34412aa3fc951bc4072c22feea35528d65a55eb554641d7ae6ce6086668e1d2758a8a7d50ddea987ad5bc2619e4be2cc8f49e10a13436225e08b7da09861207e2b7cfbd8c56d5b5dc7002fd6b3dae095189c591225153e237c703da222dac22b6897936d567222d66d2641b23037d0299b8a0e33e3c5839dc16a54e81499f2a13c305534283641e820e8363a17e62a86d49d7bb8eb85f5cfad9ea62dfc99374e0d75d5a1695bfd74b362ff561d41433a234b274c2dabdd5254561365b64968f105618aa8444daa44dae694766df7213fc4255fe4c3841ca975d10bc89b198e31531f7a14873cabfa048d00a53d8c3dca1cb1934d206ced70652fe0b592898ffa20244e23413f164ad90f7d43bf55ce346930efc89b1a4c02ccde523b408526c0970b4b6d8806510cb0d435ba7aada855c56ce66457ab562a124d591d9be210c4566bd54ce5091e39275cd2d49053b900518535a1d1c43b98a01ab99d8d41068a461831fc740a5c6a6a3bc25a16a7bfaadd80b5dd288058f341244b520b2ade65b6fd98dd197c14bd410e7b93eef102a45fc6d066610ff6af25414a7c96d9e625fbd28924bb9dd090f1f51f4b2de892ec0e536fa8c4eb80015136454c656566800d2871e4d5ce6a021db100c7296f2e0f066b336a880d24d6d5b7346cee9356f1f2426cc9d40100572a13eaa0f4d15ad5a4e24ecb94fbb2a85f0b06e9b2749758adcf88662836bfae9126f7ac9e941081288f944a84957ce3e5a9041f5ffee3990ca002596aa382ce515b27a171dc8c9cfea4ef282a25089aa99a84bd1d8e062631b7b6a00bb551f749466814f9a401b6b2a2b94986a618b98e1e076091144e628bd6619083bf8d33c36c2488be8194bcee7b95cd6480e097d6f6af604f864ff3275e02976995b7191b80b23f22cf60d11651775184f1c6088420edc352b5619f0badcc90f355575d2cbe5082e9775b01fe880c325ff688dc90e63c61acabaa1927fd89eecb7b99ce84b3ef0839887ad0bff75e3765e5ee2e09857106190e191e5437facc5a90798b442729f824cfadef839fe21daa64ba8a86ce72ce0e03e369c6b0e85aea721b9c534c900ef6db02773853eea69db49b80477efbc0e0ab92a37076a5314c181fb564affd4bfd011bc0e75a2357cc306796e0547951d0f771ec642dcc36b1e40ebfd51b06bb88a1bd7aa98d07ea217daa0ad9220d15bbaf460e30a7003a2f068e4783845230a3759ae509bbebe620a0be8807e28ceda71ed044354258f5461d42c76f510382da4f0140821527a23b220ad423126d3f6a1c18d725e55f
OutRec = 00000030000000030000100008000000001000040003c0002000000002c00010000c000180003000080002000030000400014000200008000040000000040002400000000c0002c00030000000038000100000000140000000000000800000000c000180000000080000000010000800000000200008000380000000000003800000000400034000200004000040000000040001800020000400014000300004000180002000000002c0000000080000000020000c0001c0002000000002800020000c0002000030000c0002800030000c0001c000300000000200002000040001c000100000000040000000040002c000000004000140002000080003c0002000040002800030000c0002800020000000028000300004000180002000000000c00000000c00004000200000000340001000000001800000000c00000000100000000080001000080000c000200000000340000000000002000000000c0003000020000c000040001000040002800000000c0003400010000c0002c000100004000300002000040000000010000c0003800000000c000340003000040002000010000000030000200004000140000000000002c0000000080001c0000000000001800010000800018000200008000000000000040000c00010000c000040001000080003800020000c0003000010000000028000200008000100000000040001800030000c000000000000080000c0001000040003800010000c000300000000000002800000000c000040001000080000c000200000000300002000000002400010000c0003c000100008000280002000080001800000000400000000300004000200003000000000000020000000000000100004000100001000000002c00010000400000000300000000040000000000000c00000000400014000200004000300003000000003000030000c0001c0001000000000000030000c00010000300000000300002000080003c0001000000002c00010000400014000100000000040003000000003c000100008000200000000080003400010000c00038000100000000140001000000001800010000c00010000200008000180003000080000c000200000000280000000000003c00020000800038000300008000140000000040000400020000c0002800010000c0003c00000000c000340000000000000c0002000080000c0002000000003000020000c0000400020000000034000300004000000000000080002000000000000030000300004000100000000080003000010000c0001c000200004000340001000000001800030000c0000800000000c00010000200004000300001000040002400000000c00038000200004000280002000080003800000000c00034000000008000240003000080001000010000c0002000010000c00028000300000000100000000040001800000000400024000100000000000001000080003c0003000000001800020000c0002c000000004000280003000080001000020000c000080002000080002c00010000000000000300004000100002000040000000010000c0001800000000c0003000010000c0003c0001000080000400020000c0003800010000c0000800000000800030000200004000200002000000000c0002000080003c000300004000100001000080000400020000c00020000100000000200000000000002400000000c0002c0002000040002800010000c00030000200008000280002000040003800020000800018000100004000180002000080002000020000800028000200004000380002000000000c00000000800010000000004000180003000080003400010000c00038000100000000340002000040001c00010000c0002400000000c0001c00020000400010000200000000340003000040001400030000c000180001000000003c00020000800000000200004000180001000000000c0002000080003c000300000000040000000000003c000200004000140001000040001400000000c0000400030000c0000400020000400010000000008000100001000000000400030000800024000200000000180002000080001400000000c00038000300008000380002000000001400030000c0000000030000c000240002000000001c0000000080002800010000400018000200008000380000000000000c0000000080000c0002000080001c000300004000340003000080002c0002000040000400010000400014000300000000180000000080001400010000c0003c00020000000010000200004000000001000080003400030000000024000300000000280001000080000400020000c00024000200008000200003000040001000010000c000340000000000003000030000000034000300008000040002000040001000020000c0001800020000c0003c000200004000180002000000003000000000c0003c0002000000002800010000000
Key = 4eba286d54cc289caf78c9964256be52db2f2cdc020ce12fb2c472f2e7913d0d
InNoiseS = c1e9a276ceae5b944e79f8c57ab825a58ba9d01a23cedd5b2b2172a3f8ac35e80b5a3f84c034e226219e78e800453f3ab95329bfe0f4c17246ab6193db9dbe324b5f07f0998d6d83d24208d1b51298b5166c66258d26d86278843e3ddd13da7ebe0ed24902765149465113fee9461a84af1a68c8bf76769603e82a21a693fb0442bb70f599d8982076b9fc36a42c46b75db8b1699544e557fe21330ee6b53bd2310e6dee459b7a6fb55cd640ab1881334542aa920a8ac4e77c87c60ab1c98ae888f42134db67a7b809c69fc81194c487f24b61a011b086d058cb4556b582c54e4f047f50531416539ea7c1f04e7db95bacd3afb616812285354344167ee4745512601dfdae2a9afaf531b40e16d86569420b2805722ad890ed17308035c8943a0daad4e8c8325e8cd7d0263803879ebf420df2b761a86939b4e19ab161ae22bc045acd0af1985dca8230a752150191b20890d0788b9e8e299d08fbd7664e9645c43940c1b06d1c8251cf859d158fb5b515e40c0aaccd90b370020383b71298cdb335803d4b58fd3c8217435218b6b970d180a284d17b7f61ebeb9a46b8bc476bf321010f06128c02e171763dcd10b655aa2542213b6467800f134284da21622f6c20c522d1d05adf9bed5b7a6d63a3ab7236074e1f9b999138ac258900eeaf68a8328ed5084a23cf7cbd851ba7c222d1975363a0770cc446e7c4ef51e49457eaab2ef1fce02a1629c68b12d1aaa3a9bf041a765030d0e2a719ca712fec479ae3f5a4c2caba024ddc2c4c2c354bfb5c55b62daccb7a068adb03253437f87438643ee9d86929d5681b52b87664ace83a2672daae7c1f6c6aa2c486f9e3bb31c4f27b32d047a6af990e08d36e3a8fadb376cecf67989c4977d33d56db106107de6e89849646132a23858514a8931ebd4383d2635f90b2f17b7d92eae259e6ab4da034992a1b6ff215254e78a930fa6cf12283b7d23c73e08788a645b55268ca37e6c49227bb5f2f536caeab9344b7904519509990616250f127201bf5631ec28f5b9b7897870282b69bb46a8854bb5a66f626f9b5a394e062e4208c194cd1b963747216d8975f28a2480dc04a0f31462287d463ab14969827aa2f4fc4c30e977153e9e992688c8ad0b5c3efd17a4b95ec910881311649e223dd8d9348e11f0183560b345a4064c1205d4d41fa5b2b5c60e00dfdb2f31199d8897ea960fd78e6000b7bbb94720d275d9bbc819ca124dcf706a27615209cea60b952fb90455a2bbe3d311b9da08798491684a6291e915aa80b1983d6190610a094173575a7772587408338571e8e248a0b255c18a2cf4684040d215f88da53e9a6114903c3683d3eed814de857742e76a95282d87877289abbe54efdbc9d1961b1176cb5066d3f0bf7556be86106d1d6e9a8bfa8d5fbecf460095821989abd55b60261c8287a137feaedb0515e45694721081851957e88d105db0d974d5d5cd5a9386a8a037f315abe3b809b7f1b6656ac2d269452a39868e66b8e49543584f0667614a9f0aef09a7d956370a6a58353b70196498924bfa073ad687b1ee1a768ecabb7ab15f22fbc71579f7463429d69670d2ec605119f319574e572ee229f6241fab912addb1b83d71bd143149408abb1c15bde84ef93e6d2693c9423d99128832629e6d75b682e0e0181a0dcf442b4c27c32846431a3a6d8690f1c188a9a4274bf284bf12bf0a0dc9672d358b1b6243a631fdefa6464f9463c89f7e423ce03fcd5dd22fd606372296b024baa86c8c922071842a5084a799392ad39880a8b50d9386c7d60f3920db18c1feceda8d72e36e3db48858c00b0e921e35a09e1b16bc54428e0f119b7cd07466af576ec1908f489206e8fcb16580a8271d612ef272f8a5e18c947e10ff2263b08e46527b42d1c993774ed4139ccc0b39566adbacdd1aacb0eb2aceb6dacaa2cb1818b53e8e4b2995ddbc4f399f86d80e6644a2550d129f0a21e84f8950aed8cdd59fd1d09470ea43a19ca7f6a8de69422f0b3078a87a3129a8d819478a470d0624593620182087f57c62450c5f1121486c377648c3e5118e59659c56fd408dee705beae9b412467884904c1488cea3fc51696471ef154f9547ee6ee4636ae578f0611b4311c83e744f186ce2013e8eb00633a3a9223e39ea9107a13639a4dc0457116d20899da92e623b64240d090460a43d88476564c630f99a049f5ce5e34d645c8890e71099f16ebc72121aa044685fdf187e166155736bc1429c85cab2c808c0a1eda3bfbcc737395b4845031807b872407381212efa6856b69b145db0c4fa936ad6f05a824c10f500ad9e91cca8b7c0d57e38c3b82a8bc6d8132b6ae16381604ebfbfd8e8416177ca560e2983963fb1b25ae28d85071d251493e4c27a34319f04eb387a592e62c95b7e8b426dffe2b6d2ca89a71e091bb15c542ad9cb4211cd789b95c13972b9aea65e12051af44020f52971e61324245e9154d528879e559644ec8f7470e06a6d897cb84a13a656ecd55a69dad7234c79da3450a4d
InPK = d2d75576a45915b2cfd75b4bf06b375114e4f74011e94172661f6644abce4f161ea0558ea13e358eb55f624a6191b25c6ae818f358443078ae43df8a800024254fd9191219b3ee6e2cea5fac0e0a0a5b8aff580b69972b592c311b65ea283267803a7407a663685e87419482505288759406c311ff79b69fd50923ba10120fd14849689471f3d74e74fbb17dd8a7c6e3315147b4d2b6e10b1d8e5fe5c0f9af15b7c80d2d165779a2ec26518bc9d8400def4707f2d8598e56f20501729f3fedd5fb136dba0e5539670a89906e9fab0327cd647d5a9c80e9dd5501469123deb9654d477b297cc4b4efa0f39aada4a37b54b94715a53f3b4bb2f2af109627504db876f505d020fa2103ee81862992a3be24b14749f52017460e83adf847a049108eca92294d117b1e6a146829a5b5699b73312d228a5808e1b11ff174484cf9920f20a016cb8aa461ad41ee13ada4f26d223d8e0678205a079e0de22b51a1265b86c015ab1132c19de6fb09650cb1a33f14eed944291b4629133a3c156e7bf85dfc0887a753a72a5930e8890bfb59fc1d5fe926fb30be72d520c8b6a5908cb5da4df7a34135b3862cb85c1162202dcea8a0a843ea441004d0d4a7ee90372174ba8a680b0137ec4887f44898e3c0a22e3696c33a7a76980b8f5c45ea126d769c6a337574384927e5c17090bf8a506edb6b60be7a9a7b5a32851aab83b2c4d8a66a44636261a6f0b5e72830c2edcc38069039701d58aa0f4730385f449cb3069e52b38d55f2d7ac981bfa15af4bad04200964b8e8aee47a7420f8e428ba9a5005ba89b323a8501fa3a5b0332895a865c408b24c7e8d8ae0f710880dbad5d0920bf676a1340c7e77b1fd2e890f3aa492ae2c2662bdb451f09e17623353d37eb0cd20a7c96abe0ffb2ffc42f88171374580e27b64a550ca636aed8e12758de313d2f22a6c6feec89dca4bd0cd69a5cb588b0a9f6d61a67d9ffd062627aba0653f5a5025385423a51bc5570afd0d88d196b2a8855ce606d2d5227cb1182a90b224ee39f52f5aa9d6b685210ec6db683caeaeddee41c30c26304464855b7562898482a361f4567d53c703559850d9436480c9d2923f1c4264721893798fe950b8dea6466eb51a045943faa88cf31c1e4dcac6a741ebad731a604ea3e04c558dcdbb82d361a1de843b59587c593f0c12a5b7c4acc325c41a8cc9271ba5d6763de51c34412aa3fc951bc4072c22feea35528d65a55eb554641d7ae6ce6086668e1d2758a8a7d50ddea987ad5bc2619e4be2cc8f49e10a13436225e08b7da09861207e2b7cfbd8c56d5b5dc7002fd6b3dae095189c591225153e237c703da222dac22b6897936d567222d66d2641b23037d0299b8a0e33e3c5839dc16a54e81499f2a13c305534283641e820e8363a17e62a86d49d7bb8eb85f5cfad9ea62dfc99374e0d75d5a1695bfd74b362ff561d41433a234b274c2dabdd5254561365b64968f105618aa8444daa44dae694766df7213fc4255fe4c3841ca975d10bc89b198e31531f7a14873cabfa048d00a53d8c3dca1cb1934d206ced70652fe0b592898ffa20244e23413f164ad90f7d43bf55ce346930efc89b1a4c02ccde523b408526c0970b4b6d8806510cb0d435ba7aada855c56ce66457ab562a124d591d9be210c4566bd54ce5091e39275cd2d49053b900518535a1d1c43b98a01ab99d8d41068a461831fc740a5c6a6a3bc25a16a7bfaadd80b5dd288058f341244b520b2ade65b6fd98dd197c14bd410e7b93eef102a45fc6d066610ff6af25414a7c96d9e625fbd28924bb9dd090f1f51f4b2de892ec0e536fa8c4eb80015136454c656566800d2871e4d5ce6a021db100c7296f2e0f066b336a880d24d6d5b7346cee9356f1f2426cc9d40100572a13eaa0f4d15ad5a4e24ecb94fbb2a85f0b06e9b2749758adcf88662836bfae9126f7ac9e941081288f944a84957ce3e5a9041f5ffee3990ca002596aa382ce515b27a171dc8c9cfea4ef282a25089aa99a84bd1d8e062631b7b6a00bb551f749466814f9a401b6b2a2b94986a618b98e1e076091144e628bd6619083bf8d33c36c2488be8194bcee7b95cd6480e097d6f6af604f864ff3275e02976995b7191b80b23f22cf60d11651775184f1c6088420edc352b5619f0badcc90f355575d2cbe5082e9775b01fe880c325ff688dc90e63c61acabaa1927fd89eecb7b99ce84b3ef0839887ad0bff75e3765e5ee2e09857106190e191e5437facc5a90798b442729f824cfadef839fe21daa64ba8a86ce72ce0e03e369c6b0e85aea721b9c534c900ef6db02773853eea69db49b80477efbc0e0ab92a37076a5314c181fb564affd4bfd011bc0e75a2357cc306796e0547951d0f771ec642dcc36b1e40ebfd51b06bb88a1bd7aa98d07ea217daa0ad9220d15bbaf460e30a7003a2f068e4783845230a3759ae509bbebe620a0be8807e28ceda71ed044354258f5461d42c76f510382da4f0140821527a23b220ad423126d3f6a1c18d725e55f
InRec = 00000030000000030000100008000000001000040003c0002000000002c00010000c000180003000080002000030000400014000200008000040000000040002400000000c0002c00030000000038000100000000140000000000000800000000c000180000000080000000010000800000000200008000380000000000003800000000400034000200004000040000000040001800020000400014000300004000180002000000002c0000000080000000020000c0001c0002000000002800020000c0002000030000c0002800030000c0001c000300000000200002000040001c000100000000040000000040002c000000004000140002000080003c0002000040002800030000c0002800020000000028000300004000180002000000000c00000000c00004000200000000340001000000001800000000c00000000100000000080001000080000c000200000000340000000000002000000000c0003000020000c000040001000040002800000000c0003400010000c0002c000100004000300002000040000000010000c0003800000000c000340003000040002000010000000030000200004000140000000000002c0000000080001c0000000000001800010000800018000200008000000000000040000c00010000c000040001000080003800020000c0003000010000000028000200008000100000000040001800030000c000000000000080000c0001000040003800010000c000300000000000002800000000c000040001000080000c000200000000300002000000002400010000c0003c000100008000280002000080001800000000400000000300004000200003000000000000020000000000000100004000100001000000002c00010000400000000300000000040000000000000c00000000400014000200004000300003000000003000030000c0001c0001000000000000030000c00010000300000000300002000080003c0001000000002c00010000400014000100000000040003000000003c000100008000200000000080003400010000c00038000100000000140001000000001800010000c00010000200008000180003000080000c000200000000280000000000003c00020000800038000300008000140000000040000400020000c0002800010000c0003c00000000c000340000000000000c0002000080000c0002000000003000020000c0000400020000000034000300004000000000000080002000000000000030000300004000100000000080003000010000c0001c000200004000340001000000001800030000c0000800000000c00010000200004000300001000040002400000000c00038000200004000280002000080003800000000c00034000000008000240003000080001000010000c0002000010000c00028000300000000100000000040001800000000400024000100000000000001000080003c0003000000001800020000c0002c000000004000280003000080001000020000c000080002000080002c00010000000000000300004000100002000040000000010000c0001800000000c0003000010000c0003c0001000080000400020000c0003800010000c0000800000000800030000200004000200002000000000c0002000080003c000300004000100001000080000400020000c00020000100000000200000000000002400000000c0002c0002000040002800010000c00030000200008000280002000040003800020000800018000100004000180002000080002000020000800028000200004000380002000000000c00000000800010000000004000180003000080003400010000c00038000100000000340002000040001c00010000c0002400000000c0001c00020000400010000200000000340003000040001400030000c000180001000000003c00020000800000000200004000180001000000000c0002000080003c000300000000040000000000003c000200004000140001000040001400000000c0000400030000c0000400020000400010000000008000100001000000000400030000800024000200000000180002000080001400000000c00038000300008000380002000000001400030000c0000000030000c000240002000000001c0000000080002800010000400018000200008000380000000000000c0000000080000c0002000080001c000300004000340003000080002c0002000040000400010000400014000300000000180000000080001400010000c0003c00020000000010000200004000000001000080003400030000000024000300000000280001000080000400020000c00024000200008000200003000040001000010000c000340000000000003000030000000034000300008000040002000040001000020000c0001800020000c0003c000200004000180002000000003000000000c0003c0002000000002800010000000
Key = 4eba286d54cc289caf78c9964256be52db2f2cdc020ce12fb2c472f2e7913d0d
InRandA = 115dd662e4a18f069d8ef08e92843a45f73aecf6409390a45b46d41b5f92c6a85fe601c90487263afa39a28fa153054098a02fe501abb9abff56ac36378cb6cec3f2a962f6a8072601481922bde99367e2f0b4330ed70bd8c24295c31c9965b5917ed0ed48250f42468f22bb92ed3961b6e248848e2a2565def2a0657c8b49d027a5457d1f824fd23bfaa9a813eac634dc31025fe16bc067e640da864cf22621b422ee506a37343e41a23a56b2025d325d6129ecbd47f984fe0950c45c5d2a1bda0048b8fb91984b66d4930d667ad8f67d0ad2484ecabb3e4a6a4426d225846449457e21cb429bffe97c9510822a8bad238bde2a453e193b9a6b5d1dc8ab36d9ee36633298b6754e710b52afcf043ce9b9ccc2e902ffd6617442e902e4e529afccfa91b70984921c4809e39d9eee9d5be346988ee2da5cf9863864504fcda0ac8e9dea662555476647a8232564fd46ae420463137d947915d8d3c1207a6b5a0fdb9531a559169730a9fd7e6b70ce388673cd80586d10a4a7a08d1504cb4ad8ed3c3a14b667aaf477b4155c8afe75775299cd7388f57dcc590c0ae8cdbc0e95bdc9c9f5bf0e82dbc2726cb9a60be67395febcf3ec47802ad5b0eee7a1734d016fc41bba9056568cb5ae15c71a82acf6a6f9d53e643196ed6d680a4c8e5dea93cb80e03f6203c4f1e9ad1dd2e93968eb2959095d8c91c36c8e7e98a3ea23441f1a4b9a5a3ba24592a69d386bc8a516cb4cd0498905506ed6d26c68b7ba6291a584468b708f8731d13e8634dc2ea7663825aa6e7d27370866950ae18737049cd84f0763499223b2473ed72a5207b60aadeacc68a9d3934a55c8be32b2d44f253e0daf2c6cbf6a777e4784c34de26eb2ab1656210235813817a8793108317c05a569f1b74e2f47cccf691858b28c535d873f507e65a9b9e1a6da65532af12028ddabed18dc4bb8882f8c848c9bb23c7f99d893b9375e6b14dc71f834747cca9e081198c90e589d738895fd06eb1a9674b9b939b5e7b42a2c0d1167e13c13c8e27cec18c13506de7205917d59da589c04c1f45ab5c0b3a80120f86c7021dba9bf4a05c65ad1d27e153e2e44706caac82d99a8cf40e6c59cfeb7ec07e0db3ba0163e2ed5b05c60764562d60500a69a59831178a616b1f35ebd15876062f9437f8a8e78247d0cdc41f658672f4ea16a087c0a415402792838598eae4895ab79b1c4c69d5b144c4e82eabb748eec724454c3f6f0c935349a7d51d8e5a86a50ff5146e6a4c22ce0456f6d0ad50d0778d500326ad33bf7933d62cfd334316bf182ce109b51615679c02e0165d5f8ae54976cd837661324e4765792e4681e2ef7d134859424958ca5d6e1220fc00620df4295680b84574e985e1ba7e08b752805374332867659a273d91ed99dc5774ec798c06f8298ccab90d53bc950bbea2e25492e8c67deb3874bc4368b079d2a73499fc3c51c16c6b8b704967a71b795034d1e2da91cdcb246149c270095999e6be233d86538e0e572e3ef7190d58256a188f88628c81600337a563d4179c1d9a18744cea2279551af93aa278bb88a5ffe45e3e99a492ac86bd5c8957a7c018dcfb9ff56489084af406151658fde5f0b9ca6145098c9c1edfd08f7e0e3d4c162a58628a7d23009a4e4560723a694332fca49b902396b98d014bbabd262f21b780b4a056a878b55a8921293bedf45602eed1b4b4d80717492a9bcd9b8e99ef152bfe21c205b719a1d4d54a7df9579cfaa999404a13178efb236029d52e0a261a1973c5efd966b2219847b14065856272dac65c2d2614406740aa5f9145c859a7be9d6a48b8689b2ced1959b5c8d4b18f735268e70c65b4664481801916400d2b5d0739544bbd178d12cd2d718ea06f9649feee0850fb1584d1e18568e26833bc93d53261a488d261c295d2963b706d992e01eb2d78c5e548b2d483e410ccbf74ab5aad7d0e2637e0d3660fe3115cd5cea046f4778b426d5e079f9c7f09ac448a6d5bed819ec5b8bc525e504b8079650b10ca4036557b4f91c870fa56c200f220216125739e52ebac76f85abc64e1aeb5f3dbb250e50f69756a708cdac4aef845ae31c9a03091ff6d3123a65878e08dc1cb768a6f404ef9d52da0c2ce1f52431cde64e3432982b744710550c023d699b376054445df81699d411648e74cc7506b1506df3aceb7ba80aac6b21379062346c77d5cf68dbbc12e316f823ce2c33cc24c6e22afd7ed62134d744155cc9d007e010026c1e91121292a27efcc5d0213f1996458994b02e886966e97ff8a84d106c09f84aab516cb1d0f7ca443126c30dc0062598a3a21d32cb2fea35fe51a7a83892be55ca24971ac4863b0f4d557cd9a3420ea71b1f1a61de8912d2d6d59f23c425f9ac6077e86e50c333da23c7da73a5e47a804016819bf1c2a75f6c33522a505a1a9a5e313c901214cf33533ec8a6d2218900f2856b858b9bb49255236e090a90c49c84f32bc5f123d6072517e0ea091e6a04117c60639d2ada6f5d0bcd8d5729efa7394bfc85
InNoiseS = b25e0026c0f1ac209932a42dac2b2a94f3d3a08078080b8ad39ddd85fe04106bad6c591655d7e6dc9936362a1442a112bfddef1594169d3b929b77663dae11971e713bb5d06882cc5933a4b55be9154f6b2da674e96cbc3ac56145875888931f64669d57c5637dbd469bd3b6504124227e5e86789b7403c7dcda60e2012bc20b28d116209cd9d26be498249ad7a933e63e587d4f8c8c728ef5a0e64fa532c8c56db5d629a803c451d0cabfa7fe185c559da2f73136b79418dd245cdd990fa948a7297591195b1fa8d6b953b3a4dc91692c84bada53c4ec8539394de26358102b509549a1dbaaa0ecd9a614b4e96f17d26ce3507c510d1798d11f218ce41a7900249e0ce70ca624560d0a74a23591f8fa553c1cda6b995c951ad4d965a8fea143523358b3147412422e629de92d64820fdb897a9ee22b5be0190e6ca889bf8b27914c61568bda84651b17a787d700aa1c8d0eed5b669d69b644b1283f61266f6d369a50f446e59c7bb911d1515023e484e7d949a9c6498368fd4291433629adfa93c993f5732e7e12a0cc3f79b94dbd84010f5711103f5d622fcbcbac55d511f8ba02ce47e00a4ec84d10af6684829275598c635defc620f59c5a1ce97399d12de74e9f84b8c25ccc87b4e4b7691d6cc595b40b6e7a2d0ea93773d60edb498ba0dc59906a930557d0529b4d975d68e1d0850f601b490f9a107847e909f8c8573c61927374d9a6bfac48f4ddedaeacc39c3037ecb7d251ebb98231bda7035ec9e2349ac3537496f609016d6a79d394ae43e951abe87fad7d7344148943fdb2b76b56c8e6316315a94eda5a3151a65e7608b80968442e33a7cfb1872ce5e2a1f462bd6d65c8d09a8023e944ccd88050a0c1d488843add51135b4ae73d90aef5143bf2016a668ccbfc6bc5d2275302ccb225a269dc08b26a83d96d16ab68e36eb19da009a87195e9200045d07172984ee427b983ec54af056df6caa32e24b2d579862ce60eac0a13a97da0312edf20d38cf94551a8fd61a78232b387a8b217f98ebb29737793d98a364c78a471dc04b0a3eb48cc9e43b6ae6d3875025d58e2aee7a95e69902f4c8bf34e73ce072572883aa930c1665055a07fec86c229dd9d5d4c8c80d227b278fadca1b00da0885b04c6959b96bedb6a5aeb5322a18cc116f29d3c1574cefd7513945479937a20040402011bacf9ddd010da0c7e19e8a65977d4bd96726951c18bd380c62e2fc861e338ab86587a69e49699c1587fc5737613405c50ca11a365b40ac58eb867f37d9aa61157621fb09737970451286e4e1e9d2cb01a1a0c1187bc491e2e1d75e08c02bcfe5cae870bd073ba05bf2b2f4be0d61a4b461970a5d930b5c9bf111b11252e61d3f4a7bd549ec44c0beff42a9c6273b03cad315907f490808144904388d4760e446e6bdadab21593a363f2db448987425f6963012e2803a4c50500ca9a1f22f9d8b64a4c59545bcba76813b7d41fa40d741ffa0d1ef60a040b4441951245c1b4aad9af707c1815959d0bd0bcceb80cce721b83ad1cdb9c1d5b45ae816403d63794cd285f169ec609791aa24f82d58e04436ec63d4a6086803ba584c83446519207c072d24a6ec7a696625e1cbff76c54468e458190e28e6848a4b6a52ab867fb9c0ec845bd26927d1d8b9f24f7afdc72402e65a1e0de44f45eec51585c594eebfee849f63ddc54ce073081837945a121f92e02f104c386df92b927ad02aba9ccbc2857f2557c7aae8eaf8524cae5620d86a2ebe43e40b108ea592b5450f10fcff13bf068771cc7440e7d6ae66c9af4a3340b6fcabee9ef459d8f8dd4b804717b3ec54ae2246abb7a2bd5647712a1694262eb4886befb8a11d4fd297f512e18b819121f4de1af51036a64fb97a111385d7a218ba794b9ddb7066fce7bb3f1b86590b7eb1b753a29d3bc584ecd300fdb33db715c5a15cc1bc3f2fa49a9abc52815c464af878781e85e15fee92788950005deae6822e084a4c9cbdae862c58f76a6fd25262a3a42004881a7160bf546e066f376163ee028b587014a2b2b269a19dea85c4a7690f3d2065dcb200af1e6714199d7498f3858e61d0d11e8bdaa85288c256cb8bab2982e038a084f459ba0697e7e9159ca0de7b2ecab32a8a0e2b3e26097e321868aedb9318c7972bf6e011e03db452ef8a07ce49d129d12b7e55818e9c4ada4dad00e8722764009ec09082a7870402abd180d050dab6cc5e110a290db641ae620ed5ec58a7f97821e07cb54de427454a5d90d28926af2008525d9f053487aea87972764023751e5cc959a793aa986230814082e8d0747d908027b0e0baf36e8768776a79a7056b438b8a7d3a134da4b698c8dfad12e418b2435f4aeda6cf0a6d4d4906e3d4845606947f87963c7238592e81aca8b03405365408383d120fc3178696d6599ca124fc6014ec6f2e93d274a8e28e3c64a395e433043283d81a91839d8984f642fa1c1043932596fade0cb561e08cffb08af0861535276d622b225d38c755b969c1971e24d600a9a5c
InNoiseE = 410847f4c6bd1eed95a6d38272884feff2d3d58c25185437064cc584875e0901c0fe1d81e802e4efaa0e8654f95005f206854dc318e06a6bcb022923c26e521a6d98d8b15589e4efb1d5c3f57719dcabf362f9bfff4955b81759aad88856b08c3a08d661a50bf4e5a6ed00e4100bc0a483e460b138361c0806fdc791712a840dc500bbba42f60b87b52a963d15e6f4c7053d716d0ea5c27de87d2b00d4d60838760f56c570fd6942340dc0733f708493a99f78e81840da8fc4d94c914e01ce5cc4cc8183d6972ff4029537a18c756bc35a24588e3fe05abc340c6d593b68585293c04afbc18c179d8585c2a5f0aee36c0ae37ea8694fc79c51c5a87faf6126b766303a6963844b8538976752a363847064724018c939e1763c14a0b3667d841651f1b3753966d22c9bf76d2e0de9ab2091f1d439490fb796acdc55a34dbd02417d5914a55fc1271827c6d77862c330bac48c9ae334d20f499555c872716afdc9f6b219a18f7d47e608ebda1617c547903d6513cba84ed05132ab08272985778654bd1220534ab1134b5595b1880864224c316126547a9bde73001dc49e0b86516aa99951af2ab5e5417d2ba51032976d9449b58ab8d13d5e78a219beb77159072a27690842b134321f2a21508821c9810ed5bd4c1715d8bc02108538a01cd9517428a4cd4331f3a216474825ecd7607e3b2f5e6f08bb851e405b6995b11a5dbf2a72c4a0624446dac7c4e0d89eede099c9292567b318c81702268e1d9932b87ebebecb4ff258a428ab724993583f7e5123ccf2799e091d81a2e4723d9d71a8e40dcb29d8846dd910fa433436b005b624f16932d38321e14c6a41494ef3446c85b8f1d4607943868ddb9556ab50f1a6c10fe30055c699501a3c9525e60b7de7ca304a929b71eac5a903dea06f442882ef5594f453cd15c1be16b1cabdb200813c00e9cc0939349ba25643c968091de29e35d20015a3c89fe5c38f9c9e06402524eada65c7d344249a0c7c315b841bf5402c7241371718b22755ce4cc6d7b056031fc902ccd43f089db16b2b0e98fca82085ba4d8d8e1a00a4751c3b39d8956adb4154d42e100ae3916ae107ba130cb64a756666e4d9655f27d1e4f075a1170b24c873c919000222a413ba0d57a8cf2ca2d3313e3410be1369e06bdd4bab58d8843dda874d5420e458f32fb7c4e7d5b281a27aea3cf82a85d416c79b7a59cbd6ee2929c0307d13f0e8911430ce1b2f778481bc451da9a4677cb28858ab34f5983076c720871a9e1d0853af298369b6906cef6630c802ce4d868996e82d28c5583870e98d5695928abd709a2501b9c383b6022109223ba1b8a7d66358c37ef0518d484f7afb31199d1f4b0bb8509ad02fe8f52e3095f5088db3419081dcc4c66bc46558e8618e2ae52ca3bba1e2423824ad496046a3c72c4877c178478bc635061bcaa39fce6eada2cf50463c8023dafb634a5094179a208b18412a145aabf2f018a9fad81d941d529d46a534d8fa827525c363ea52463473e22ea27f3002c362f96a8e8284a9103db4b7328790dd537a6a387810e777b6c52c7cd989a208911a2d8d9e3e36adf4baed646b34fe397e1754981b4afa1d7917d11b6a623832113883c88d00766bcb044888bd76dda1b08cd47e0d6bf8a8e6c5675e9406682daab1a78cb736e22ea477c6b99091e53c4f41d278d37d9b6926488a54c93100698731a14927c4a9743980964fcb29f2641ed6534a0b21879776518711efd92635790ccefea8acdc73eeedecf345a1a92085f0bb3d34919e85cbd8c84a752ad9ccbb192911645c87677e3e1c61c556871ca9b09ae567c488d888088fb11130615dba6448c7b14d9b4b533ee1036451f3084714d8a2974c2448295e4479d76bf8e0bb4a4858a02924c49e7ce5c80111b4163139da0942aae538198d72d328d8bee651b85b11225a572f1c399d2e7309ef52770a085e241abb1969de0047574c46176a687a58de29b41a0ba02531586912397eda0e783dac53ffd9424b1172b0349ab3d16138079de655f95c9644640d4d5b8b82ab2b1ff8644d8485f461deb18579753b1ba189820226d7dad76627769e909bf6e6c10aad8c2e89db4b6d09481bc938223a46ded67842fa3c0d02abf02674bd147c022ce97fb67ccf827de700012c494223da7d6d60d86ef0c224714ac2858013e0690c48e75430c31689ee55240be39843bd6d75954dec140be06053073818374c08465d629ddbd6810966788e76e88cc4057024eceb2465200971d29d13d906d1584de81b5a4d19b78ec654202379a3780ada0937783fcc2fe582c5c92a04ef9223f9be72ee12f73b1d815863987cc07662450f41edc90e923c042d748559265e8bdffcf1e3a0220c2146417038565ee46dd5b9393dbb2c1a36a3a80fa04b91d623e89297e31979b70e4d53ee7472c5e69e18c2e62ad0fe7f51488df6b06e0ce96525d6862c322f40e069bf843ea6d511aabb92441a0d4ac7e2627c28e7ae654f12997babb4399ba84bd923d750791c9a
OutPK = 7d49b21bf5e4a67ccde547f4783aa0000ca4174eb3e1557c33a9e934e0a29294662961ad6c55a4f301adf396d0ea8a7480291bf130682239040830034b247e2f5db7a8fba80689d9dca8b9403414ef2963cf600c2ca8b219606802fbcc691145cd38dde3330073c112658cb3f49d6d1a0a88f0b21114af5320a2b9273640d9131e78f60189122f26983c1a285ea26b6b23f0bb30e619a9dcda9dc3ebd885866271476a6ef088e26c4d1400c707d6455663944278347942858990c8597b38cad094e9118a3328cdd55a3a36a14e5594e0750c0316ee00b73e476e49dfc23ede180b621f0b4e294e045d6d40de291736192f93dc2996560561641a1ca94847d301a3982c06daa93a27ee1099659c866766599dc66d970ad48dfd92cdf611414910dc62e43f9192da51f3f62b9cb1639731082dfaad3a1851368620720f271aab645ea69aade694f3b1b8d556354aa25553d41fd9d6b1807fda9575fac5361c7c659eb487948046983a0b3a3c0d79edeac375e4179851eb20d029a49f55f3cab6ba07f1d9b8104bb11816a03dd700e2349eeb1ec5bec50b3fc32191fbccafdf90baeb5971b277c23e43d3205db85b5dd52f1d712a18c89bcb5416b9236e045de1b86754f3b24fa84cd82206218622ac2bdb90f9745d57fda12ab4b8466d7c86cbf57b65b103cf002199854925d38eea4a7e8b52def9049a41a6808481f4b514312797c6e22ea12740951fe06ce938dc249085aa31762225f9379250a4cf2b30e64b5a9bc04b3f2b69e505a9ca102765c9ae740daea6149db775e61f1b4a2db7a251b851eb394971d6320848dd1ede24d4c68b7139c40e5303fde09edbe6aa200802ac3d9d1411d0ce6ca3d8c793895a81cbe420719e2c45696a4ce8b9c0791cc9c999be0d22512b6c649dc24fe111ad97545a7f1cc72fe49d0c96d688fb0b8131b420cda989b5dc172922b11972dc1db5115483739888d7e5da77292534900cc2f2ae3dab61142bda269d20ef5414bb0fc9375e486158a5b41affe4862904f407bde90226c0308dc22bf63467fd02fa4696b1a2424061460b41feee968fd396b6cd12a3bfe067d831e541c8e29a9a2d724440acdc545b7ca593a5fc71f1fa069aca45cb28348eb450d1fbb0a55afd436feabc545c749c2f39065684e84013885c8452bc22a4ea411a93692bef741035bb5dd643c61a8822fa04a51751d8a005a91c36904a86172b11a52bfd18ab167741a27e82699763a8832ea73d5d3daa51a02b791ec062860440b029b3008e2e5c2846bf88388070b39e2156a1c28f1bd91846153c9a3449756b90810ac46a8c404af2bad14f71b636929a319ce7028a8556541fb2962995ab3561833a0e80629d8c9679fd5941dcc3972845f05e0f560870a12c29feeb104722f13410d7d9cb0c9a80518e0270883654d0e7446512ac3dc8563421eac4a5a50f33f84ee9afa82e451b9c469e26d862d7f2ee450c2ad7b050b9b76fdd5cc12f148517c8fd275a2da7a6a54eaa990893ad97b8234bb63340e2ada835bd051a6bc3eb9d7a5b1e5b89a2bce85fc541d5b542f054a2e495f4a5a07ea0a87522781c7312df0bf5c130927f1df0890e681bf3a986f63f500b9c4f8884873e12aa2c4c69b8982cd4530ddb0c914b6b1eb5e1bfc44f32d68e737f8e76aac22c51a76c8b1a83dba8ddedaa0b87e7d2dbda6ae667e2d3fc280defa6745a2a92b61941e3e83b2d053557f7fae24c907f9c6542805548f16664842e443c28c15b45fe5e2f7dd44485b120adab1445a55aa5a85025e52764213dab690a70319939ad971d81d5745d5fd4d03427b07d1b9d46859f3a67c6e556f5552a448ba312e61f4d32195fa2d8afd696ad2d5431c6a18ff02fd4281aa87d714350109d963f3e809cc4c9c51a3d6cd140274621af026df3663c1abad25a13092a9d42880dd2ce1e121c418f9b87c8b6bda67469d7b047e693c5ea3de27b272d30d39564082217c3aa294daf5de1428b3a1182e7dad9935e192d64c7f2ebb1357cb662ee6a67981f5ba73c8494c693d3280f47ae3ebf5fc6b9f52b044ec52bbaca15a82b169adfaa89c511df1be347829286846af2d797714bf866cd5aa44a557fa7f8cb40851fe39f3c468f8db78e867c917e0288625e271007a690f206cf443c7e52dc29710bfa4505912dc4930b7923d29bb304e13a26aa80e18403a4266c87e304b3a87a58a0f1864da113110236d371f63f4f9cb2724679bec457ed715f797ed6ab4c76de8da2ce6849858bed5d6c108b18ef2e75b5c22384286c8767c66f028cdd7b0043d6931eb12a0847ad660dfc030ded0e0acafd3d38214897c58cbfefefd8d1c07c18520082f9c63c45ff57aab3132caaaa5b94e289dc2b6f49e6d2d6a44bde58d6462424932d146d9aec4c30c0ac0e7ab0e986952f75e73e1e3d78e7e898c688a1f412a4c61f559fc8467f66bb5a7af8562e9415025dd8c70673d762bac81e4100a9b85d031a46d66df941f51c88468a820660170e032252811ce5625307e9a0
InPK = 7d49b21bf5e4a67ccde547f4783aa0000ca4174eb3e1557c33a9e934e0a29294662961ad6c55a4f301adf396d0ea8a7480291bf130682239040830034b247e2f5db7a8fba80689d9dca8b9403414ef2963cf600c2ca8b219606802fbcc691145cd38dde3330073c112658cb3f49d6d1a0a88f0b21114af5320a2b9273640d9131e78f60189122f26983c1a285ea26b6b23f0bb30e619a9dcda9dc3ebd885866271476a6ef088e26c4d1400c707d6455663944278347942858990c8597b38cad094e9118a3328cdd55a3a36a14e5594e0750c0316ee00b73e476e49dfc23ede180b621f0b4e294e045d6d40de291736192f93dc2996560561641a1ca94847d301a3982c06daa93a27ee1099659c866766599dc66d970ad48dfd92cdf611414910dc62e43f9192da51f3f62b9cb1639731082dfaad3a1851368620720f271aab645ea69aade694f3b1b8d556354aa25553d41fd9d6b1807fda9575fac5361c7c659eb487948046983a0b3a3c0d79edeac375e4179851eb20d029a49f55f3cab6ba07f1d9b8104bb11816a03dd700e2349eeb1ec5bec50b3fc32191fbccafdf90baeb5971b277c23e43d3205db85b5dd52f1d712a18c89bcb5416b9236e045de1b86754f3b24fa84cd82206218622ac2bdb90f9745d57fda12ab4b8466d7c86cbf57b65b103cf002199854925d38eea4a7e8b52def9049a41a6808481f4b514312797c6e22ea12740951fe06ce938dc249085aa31762225f9379250a4cf2b30e64b5a9bc04b3f2b69e505a9ca102765c9ae740daea6149db775e61f1b4a2db7a251b851eb394971d6320848dd1ede24d4c68b7139c40e5303fde09edbe6aa200802ac3d9d1411d0ce6ca3d8c793895a81cbe420719e2c45696a4ce8b9c0791cc9c999be0d22512b6c649dc24fe111ad97545a7f1cc72fe49d0c96d688fb0b8131b420cda989b5dc172922b11972dc1db5115483739888d7e5da77292534900cc2f2ae3dab61142bda269d20ef5414bb0fc9375e486158a5b41affe4862904f407bde90226c0308dc22bf63467fd02fa4696b1a2424061460b41feee968fd396b6cd12a3bfe067d831e541c8e29a9a2d724440acdc545b7ca593a5fc71f1fa069aca45cb28348eb450d1fbb0a55afd436feabc545c749c2f39065684e84013885c8452bc22a4ea411a93692bef741035bb5dd643c61a8822fa04a51751d8a005a91c36904a86172b11a52bfd18ab167741a27e82699763a8832ea73d5d3daa51a02b791ec062860440b029b3008e2e5c2846bf88388070b39e2156a1c28f1bd91846153c9a3449756b90810ac46a8c404af2bad14f71b636929a319ce7028a8556541fb2962995ab3561833a0e80629d8c9679fd5941dcc3972845f05e0f560870a12c29feeb104722f13410d7d9cb0c9a80518e0270883654d0e7446512ac3dc8563421eac4a5a50f33f84ee9afa82e451b9c469e26d862d7f2ee450c2ad7b050b9b76fdd5cc12f148517c8fd275a2da7a6a54eaa990893ad97b8234bb63340e2ada835bd051a6bc3eb9d7a5b1e5b89a2bce85fc541d5b542f054a2e495f4a5a07ea0a87522781c7312df0bf5c130927f1df0890e681bf3a986f63f500b9c4f8884873e12aa2c4c69b8982cd4530ddb0c914b6b1eb5e1bfc44f32d68e737f8e76aac22c51a76c8b1a83dba8ddedaa0b87e7d2dbda6ae667e2d3fc280defa6745a2a92b61941e3e83b2d053557f7fae24c907f9c6542805548f16664842e443c28c15b45fe5e2f7dd44485b120adab1445a55aa5a85025e52764213dab690a70319939ad971d81d5745d5fd4d03427b07d1b9d46859f3a67c6e556f5552a448ba312e61f4d32195fa2d8afd696ad2d5431c6a18ff02fd4281aa87d714350109d963f3e809cc4c9c51a3d6cd140274621af026df3663c1abad25a13092a9d42880dd2ce1e121c418f9b87c8b6bda67469d7b047e693c5ea3de27b272d30d39564082217c3aa294daf5de1428b3a1182e7dad9935e192d64c7f2ebb1357cb662ee6a67981f5ba73c8494c693d3280f47ae3ebf5fc6b9f52b044ec52bbaca15a82b169adfaa89c511df1be347829286846af2d797714bf866cd5aa44a557fa7f8cb40851fe39f3c468f8db78e867c917e0288625e271007a690f206cf443c7e52dc29710bfa4505912dc4930b7923d29bb304e13a26aa80e18403a4266c87e304b3a87a58a0f1864da113110236d371f63f4f9cb2724679bec457ed715f797ed6ab4c76de8da2ce6849858bed5d6c108b18ef2e75b5c22384286c8767c66f028cdd7b0043d6931eb12a0847ad660dfc030ded0e0acafd3d38214897c58cbfefefd8d1c07c18520082f9c63c45ff57aab3132caaaa5b94e289dc2b6f49e6d2d6a44bde58d6462424932d146d9aec4c30c0ac0e7ab0e986952f75e73e1e3d78e7e898c688a1f412a4c61f559fc8467f66bb5a7af8562e9415025dd8c70673d762bac81e4100a9b85d031a46d66df941f51c88468a820660170e032252811ce5625307e9a0
InA = 115dd662e4a18f069d8ef08e92843a45f73aecf6409390a45b46d41b5f92c6a85fe601c90487263afa39a28fa153054098a02fe501abb9abff56ac36378cb6cec3f2a962f6a8072601481922bde99367e2f0b4330ed70bd8c24295c31c9965b5917ed0ed48250f42468f22bb92ed3961b6e248848e2a2565def2a0657c8b49d027a5457d1f824fd23bfaa9a813eac634dc31025fe16bc067e640da864cf22621b422ee506a37343e41a23a56b2025d325d6129ecbd47f984fe0950c45c5d2a1bda0048b8fb91984b66d4930d667ad8f67d0ad2484ecabb3e4a6a4426d225846449457e21cb429bffe97c9510822a8bad238bde2a453e193b9a6b5d1dc8ab36d9ee36633298b6754e710b52afcf043ce9b9ccc2e902ffd6617442e902e4e529afccfa91b70984921c4809e39d9eee9d5be346988ee2da5cf9863864504fcda0ac8e9dea662555476647a8232564fd46ae420463137d947915d8d3c1207a6b5a0fdb9531a559169730a9fd7e6b70ce388673cd80586d10a4a7a08d1504cb4ad8ed3c3a14b667aaf477b4155c8afe75775299cd7388f57dcc590c0ae8cdbc0e95bdc9c9f5bf0e82dbc2726cb9a60be67395febcf3ec47802ad5b0eee7a1734d016fc41bba9056568cb5ae15c71a82acf6a6f9d53e643196ed6d680a4c8e5dea93cb80e03f6203c4f1e9ad1dd2e93968eb2959095d8c91c36c8e7e98a3ea23441f1a4b9a5a3ba24592a69d386bc8a516cb4cd0498905506ed6d26c68b7ba6291a584468b708f8731d13e8634dc2ea7663825aa6e7d27370866950ae18737049cd84f0763499223b2473ed72a5207b60aadeacc68a9d3934a55c8be32b2d44f253e0daf2c6cbf6a777e4784c34de26eb2ab1656210235813817a8793108317c05a569f1b74e2f47cccf691858b28c535d873f507e65a9b9e1a6da65532af12028ddabed18dc4bb8882f8c848c9bb23c7f99d893b9375e6b14dc71f834747cca9e081198c90e589d738895fd06eb1a9674b9b939b5e7b42a2c0d1167e13c13c8e27cec18c13506de7205917d59da589c04c1f45ab5c0b3a80120f86c7021dba9bf4a05c65ad1d27e153e2e44706caac82d99a8cf40e6c59cfeb7ec07e0db3ba0163e2ed5b05c60764562d60500a69a59831178a616b1f35ebd15876062f9437f8a8e78247d0cdc41f658672f4ea16a087c0a415402792838598eae4895ab79b1c4c69d5b144c4e82eabb748eec724454c3f6f0c935349a7d51d8e5a86a50ff5146e6a4c22ce0456f6d0ad50d0778d500326ad33bf7933d62cfd334316bf182ce109b51615679c02e0165d5f8ae54976cd837661324e4765792e4681e2ef7d134859424958ca5d6e1220fc00620df4295680b84574e985e1ba7e08b752805374332867659a273d91ed99dc5774ec798c06f8298ccab90d53bc950bbea2e25492e8c67deb3874bc4368b079d2a73499fc3c51c16c6b8b704967a71b795034d1e2da91cdcb246149c270095999e6be233d86538e0e572e3ef7190d58256a188f88628c81600337a563d4179c1d9a18744cea2279551af93aa278bb88a5ffe45e3e99a492ac86bd5c8957a7c018dcfb9ff56489084af406151658fde5f0b9ca6145098c9c1edfd08f7e0e3d4c162a58628a7d23009a4e4560723a694332fca49b902396b98d014bbabd262f21b780b4a056a878b55a8921293bedf45602eed1b4b4d80717492a9bcd9b8e99ef152bfe21c205b719a1d4d54a7df9579cfaa999404a13178efb236029d52e0a261a1973c5efd966b2219847b14065856272dac65c2d2614406740aa5f9145c859a7be9d6a48b8689b2ced1959b5c8d4b18f735268e70c65b4664481801916400d2b5d0739544bbd178d12cd2d718ea06f9649feee0850fb1584d1e18568e26833bc93d53261a488d261c295d2963b706d992e01eb2d78c5e548b2d483e410ccbf74ab5aad7d0e2637e0d3660fe3115cd5cea046f4778b426d5e079f9c7f09ac448a6d5bed819ec5b8bc525e504b8079650b10ca4036557b4f91c870fa56c200f220216125739e52ebac76f85abc64e1aeb5f3dbb250e50f69756a708cdac4aef845ae31c9a03091ff6d3123a65878e08dc1cb768a6f404ef9d52da0c2ce1f52431cde64e3432982b744710550c023d699b376054445df81699d411648e74cc7506b1506df3aceb7ba80aac6b21379062346c77d5cf68dbbc12e316f823ce2c33cc24c6e22afd7ed62134d744155cc9d007e010026c1e91121292a27efcc5d0213f1996458994b02e886966e97ff8a84d106c09f84aab516cb1d0f7ca443126c30dc0062598a3a21d32cb2fea35fe51a7a83892be55ca24971ac4863b0f4d557cd9a3420ea71b1f1a61de8912d2d6d59f23c425f9ac6077e86e50c333da23c7da73a5e47a804016819bf1c2a75f6c33522a505a1a9a5e313c901214cf33533ec8a6d2218900f2856b858b9bb49255236e090a90c49c84f32bc5f123d6072517e0ea091e6a04117c60639d2ada6f5d0bcd8d5729efa7394bfc85
InNoiseSP = 55a7fa5b24024bb5e137b7da38998792e82320c91e6723ad06f209329f90c23707823be1ed092b16c44df82eded72c0819d42c484afa9575a11219e6a366a1eb9e6f659f458fb0432c888f6142be6f2f437ec4426b6d4f4103fe6428460e825d252b314fca0b32fd48d6afad55d842a0201aa9bb5ac664188ad119773d23f9cdce67850849cb42c76a2ac292a6dadcb60c5da1fd155419dedd9ef5d854cbd5910679ed5a51c5319f40dc5392de54b6a8d0ebd9b0c16ac8896d346572388c55c7fb9f3d6212eb51218b3c03644d6140a680270b51da06526c7ef4eb09c1043eb526a732e6509c0c0f6841da48467637ce94f88bf8adf841015aeeba5d979a783345f2652ae261d5fbf8957b0f20ab22f28d1edc65662adc042703deeb5d953855570937fdc226f76b444b05b85fdbaf615bcec839d0252021d7960923915d59a2ac6d1bcd8752c548aab3094fa27058bc5707bdc7a84488194c1c81e598bc2fd736eae2f945c3d07e6b9346203a48ebd7f79d4f8b172b74b79178f89bc766bcf63466571aa7548e66cf58ce2a0ec5a56dce10d006bd91c183e2a9ffe42f0e9496f713c905d0e4fe923cc8a2a85afb303a0d1bc429c68b209d9aa9a6aee3be4a8507e462b307ed443fcbb17a3172b4754a499a7384583a006897dc507589007bb20db84987d9d039b698af3392bf24b74e3ec59113f446cd972f4624465b81a5b6000dd89f88a694e941e7d2443f57137e78bdd66241801f8a90cca01148b3ab32dc057227f098936ea884a4b187889657cb9e81e1332caa24a806eacba46ade6022fbb82119f9d46b175c5a7493d59cf33bd5a4bdd0d1078e1c2348e4bde86b4071f6055f78c5109dd662c9fb9e98ad888e88a51e447b2f4a8ea5cbf8182083d7f2fbb93e248d39560e7a3e530ec72a4f8d4bd30fca930e4d7d4fc90ad4f5702bc9df4702521a2ae7a3dc701cf816bb5d24c0d17a56248a6ada95398d12ad80daee4806788c45017f500903c671b8305da3a5589ea5be3a5b6ce4435bc79215a82e23e2c4de860cc519701a94348eccbfc6473643d4093febd70e6fad8207f1367492e9de62b5e0722f76e914e4b670123c8ca5e61ac8a41e547dd22db952e4a71554fd304f1f45f841c71291c02054ea49b285360131d9914aa98cc3ed091ce0653aecd03653d6a4e393b190f1dc5d794214a294668415c99c5af27881acc54d6786aaa1bd2bb218c13a0d6c89a49689a983dae0a8655b6e64d66069b4b6c19623e34474b6bd0a020bde5a39314b5b91ead5852d9cc6e3bd45a4aa079f4199b293c9aaab8c41c1546c736b8f5b24b7a6a859410ea58f569e4edf3c953398bd490b32c9856c0b1891e17aa06e1c6788d6803496b50fd969b80f2152fb4263a1e3583d33e0aed9421d93c322c5869c341a4c109c092f7e2d5f544d344f688ddce65e3ad5a5bbccac709b963d02de9d8b6339923d0822eef1fff5b3a9957beb3a342c230c37b1e01938819bc2b70cacbebfe2493040969610a556711fac49dbe52cd71af4042a4431f574c43e846b1d7604c598d6632bd2962a3f48dd55da79956c1c4ca1c8ca8e79aaebc10723ed045b1c24249c36ab4cd0b6372ba9389769bc55f1c497ebd6b4ebf4e1b8528fde631ff4080d2eb3669d827c4864f7e96cad88b76cce3b02712bcf61d7194c31032b9a42018128bfa5af3d026146356f89987882e547d56301861f7c41574c984a0f5d637b0bd870205a2e3c1ae94605d5599650f50a9c8885db20c5273db062a1c3149826446d12d0d491ed95052c14433b7e1c52701ec8c2f555b79664e37550001148e241521af5b0d454e05100523ec28d8d57191c9e32c5365b6f7d8e750cd2c7aa461f8d97da4b75d94665a2c9566fc9a99064cbc6f012a04b8001a732f21ec5547160d37068005157f5d6696e16e198b1b1a1a450da9357a2f15baa12904695c4b202d5ecd8ab2990c7db893662ec6499461c043ae168b1dd1178cc78badd882aeba252229989de627954be86d685f567a459b624a9f3054553318b7ef7702656a8e13fe9a4feb50a91a15298908df8e89230f4c95b3f578710159007d49589e1428e1eef972f070b3c96efebfa87e0a942490a85131d5c4764968d0269cc6c6fceb5b897b2a2c7d9c9f8f4081bb1187da9db021dc8d8c87a02d45af155bb947fe6a381a9761641545e30539e92408170c7e5a5a3f3f0637a284d222988038e219aab72a036daabc785a7e57deb1360b789f0762acd555a5ab179970ccdf7483aa8d6681801f8524816ed00485e5e48a6a427f9368a60ca15da55b27d0c2c50bb4a312a1ac16dbc23c8e22fba9dd8d83bdc64d84dd2f7b8960feeede0c32fc59d442dfde25d1220898bddc2455ab1e10373e73c861efad11619d456152020e3653c56b275cf34f4775cbcf94047a4b9387ef3d8155af9303e868ec8926afa50418702c336c404a30d27062c4d31f8891022383e4951430a2bb1e99497ab54e1ba8871bf51b6c5eb208d88a437c5167929
InNoiseEP = e1ead35290020eee908a1b102075c6c1e10b14684aef1e9591aa260b30d6e6d5fae61c8c2bb209e08ebc6de547c940657372687067629d50291347748fec50c4ee0793d4b8b6e515a20743580d856b42173784adc45101e4251e45b866423920191826cb512a87b5867b036e7962c0b842cb14188ec918194c5a68bfed117656752061202710141456c6acafb810bf0a0808beef8af48495e837509ee324e75191dd20b8e96bae2382daf1098f719090c15a46e55d1c8f2a4126e182881162d8529b60877ae1a2851b00330ec0d1062ead8f33d7188159d2741b6e5a71c7590353e7d293f204296fe050872c184f17eb1e682510633857cba3e1b57d21ca19867a9e18766601c434b1a74567c78767e57db9ddbe074db07f0d0ed00b68a26b2c6e2037b8e008b10db3d0145db460981d00aee53626ee575297901f780e4704b0ae258692c61805cd269a9fb5cb45fd8e864003975c05875ac08ff4dd34a51964ed366ccc4b58d60ebbd571600f5b2b3249508d77d96723fcfa90c30d19e04d51b9ff9332764e592595eb2a9bd8d4219a57ff803a6a04eba2c8e047896c82e24e3151b9b17def1f461d96529d58bdd456926b64165404faf20b461b7e9b3196b92042188144a9121414ef26395416725bd157c25e642b967e684116942fc1d59886ed30fb12f42b927e5e8a8a08d169301a08c794b9f29614062256f9ee300a1001ceb3e52291a98ab0487bc942510115706c9008735823d8a452af404ca1db9e4c72b6580e90351d639bd48e352c4d6e880dee2b45a11e9a0606da45751485d004e09c0e91e9951c3aefc9aed888f2a8db79acb117a3d81cfd812ec3c1f1f07c01e0a979c30b45b42ee7c979ab75b76816c38a19b581739cda62ca5e01344c0471c5c60d6be6dc22ec441add572d83940582842828b946b43857022f03c70425f169c825fdd24a9e11afdb75e6827216f7367a848d195d57761c106536d29f8a553055fba6b0c33d0198b05f52982bfc4e54205c4a56b69b5f4dec2594f18bafc89560ccb056ab2c5cd36f891cd0dfd0a9172dbd272f899934448a9cd32e8b4a483c84250c472f2e923cabd6a7a1cd73f41fe3640be880095afeea601c4b85e1d63ba4d5a6e88af2208c8c91e392f6b41aa1bea021f9845bea432b8d7440c4991a250e072a5ab50d2bd664a0af38967269f6173d1e8679840f064b4eba7f402a20462d44446bb093903482d506579459843b054e579986627803e1854ad5ed3de36e23d5dd14911c558255cfdd59c5e822113a248504e70537471a442dd4e2d11871aed58ee8060dac6073ef4f804cec2e7696be4155e1733c5ae969106455a2d02f02fbf06e4558eb33e3fa397562171862c55b4cad80080b86b0a98e6398dc1573699d5ef3bd369b8ca69178844c9ae7641951489506a1cfdec940fda8245fb2d83a19b105ef5079d8ce424a0cc2f964ca5b1aae8a5a7a7a647fd0d2279f8ebbb446d502346140ad14f7b5fce594f8d043b2968673af0f3e60543c783dc39157600120229b4f7259aa8d27080efae4d64aff5306d4eb02184b4ee30b36fa501f91ede3aca2483b0b62d4e6013e4fd47bc2bad8a02eedaa88b7bd2c4041168bff45092b27f8f8ceba2286cdacf5d6a55ebb2bd0d589a4a63e499719eda537a8ec0350afc27dad5c67d3de7d2f1497bf90f8e917424bc0b36a21647f1f507a38cd2435a7ab1aa14151c96ff40bb23065b322fb83464c79008055d24c6abf10d54c909995018992c3ebecde40c21ab7b8ea55b37fc57e11af58bdf2c5bfc071203d6daf4449de620a7148e2a9454c4537e86640e4dd4a44e4e2c049f9a19e68c8aa2322a6bc5df7606f727df98f9398099546011751ca49643ff3d4a6aaeab00702493a70dd345b72d6f459034e84041418348178bc710bd0e411107e5dcf4390deca0ebb081ab0c886117fa191388db4793f01ae4b8e0c8edc973a50621aa51d4f06e5f0c2a269eff52049300344d32f78e2029b7c1c3297d4984a180870c5b636954413e73bb6aebcbfc027375b4550faa37062969da41be13148bf8c08bd802ee5fd8963a847598522b977fb9c20db45905b840f6981a62403de15c5b7395999b450b967fdc124ea6f0ec840b488e51f68f9f53da25415be43ea864923ee3b40441a674721e435087e4b8ec108a2b7547f02089f718112b363a92f0207ed3d56c2b465e11d0f99a4c3d9d93463fa6beb4198547365d4d1429e5d81438ec8f316947ddba05bfb6c213871c4a2f101c04e9d81c531b89aa822ddb2c84f9c3b465130e2418e6069cb0698ae7954cac5498154402237d7d4908b587509664a549c458d5e564cf134e44235db3b60edec168585c638a78003c6ee44f67366b7476d8ae3dcd24389e51bc0354c8066ddd830971aa538929d7925ae6c83c65807309ca2628e159641dc669b1e652359801aa3257d2109aa35f825c55b274e362e0005b1b5b0799f53d01a46d57ca74d93696b0a23370a56282a3c2c51eaaaf80e5e22
InNoiseEPP = 00b001600000c0fd2f001000000002c000100000c000c000f0ff02000100000c0008000040ffebff02c0feeffe1b000800ffefff0b00f8bf0100010000fcbf00f0ff0b0000c00380ffebff0a00fc6f0010000c00feaf000000f4bfff6f0000001300fe2f001c0000c0fb6f000000ffbf0140000000080002c0feebfffabf0030002000f4bf00f0fe1b00f4bf0070002000040000b0ff6b001000ff6f000000fbbf03c001500000c0014001300000c00200000c000700fe2f00fcff060000f0ff0b0004000200fffbff0e0003c00030000000feeffefbff060001c0ff3b00040007c0ffdbff0e0000f00110000c000240000000efbffc2f00ecff0e00014000e0ff0e00fd2f00f0ff12000240ff0b00ffbf0300010000fbbf0280fe0b0003c0020000ecff0a0000c000f0ff0a000040ffcbff0600ffafff3b0000000200001c000800fdefff0b000300ff6f003000fcbf0080ff5b0000c0ff6f0030000c00064000d0ff0a00ff6f0020000400feaf0010000000fa2f000c0007000030014000040003c000f0ff02c0ffef002000f8bf04c0002000f4bf030001e0ff0a0000c0ff8b0008000200000c000c0000b0004000fcbf01c0fffbfffebf00c0ff0b0004000030002c000400fe2f000c00fcbffe2f0000000c0001c00030000400fd2f000c0000000080ff3b00f8bf0480001000f4bfff6f00f0fffabf01400000000400ffafff3b0000c004c0ffebff1e0002c000000000c0ff2f0120000c00fb2f0020000400ff2f00d0ffeebffe2ffffbfffabf02c0ff0b000800010000100000000280000000030004c00000000c0005c0008000f4bf01c000000000000030000c00ffbf02c000e0ff020000c0ff0b000400040000d0ff0600064000400000000100fffbff0e00ffaffffbfffabf038000e0ff02c001c0ff0b0014000280ff2b000000fd2f001c000000ffef0000001b0002c0fffbff0200feaf00100008000040ff5b000000ffafff2b00f8bf0180001000f4bf048000e0ff02000030000000f4bf0500002000fcbf08c0ff0b000c0002800000000400fdef00200000c00380ff0b001300ff6f00d0fffebfff2f01e0fffebf007000300004000000000c000b00fbef01500008000140fffbfffebf0100ffcbff06000980ff9bfffabf00f0fffbff02c000400000000300fdef00a0ff02000480ff2b000000fdafff5b0000c00300001c000800010000e0ff060000b0006000080005c0fe2b0000000580ff1b000800ff2f004000fcbf0200000000e8bf01c000d0ff060004400100000400018000600000c00200005000100002c0000000ffbf0030000000fcbfffef000000fcbf00c0ff3b000400fb2f004c000c0005400060001800024000b0ff0200ff2f001c00fcbf000001f0ff0a0002000030000400fd2f00f0ff120000f0ff0b00f4bf0140000000fcbffeefff0b0000c0024000e0ff0a000070012000ecbffeaf0020000400fe2f000c000400ff6f003000000003c000000003000480ff0b00040000c0ff3b0000000070ff4b0000000040ff5b000800fbaf00d0fff2bf00b000200004000180ff1b00f8bf00c00000000300fe6fff2b000400018000200000000280ff1b0000c0fd6fff0b0000c0ff2f010000fcbf003000bcff02c0004000a0ff0a00ffef00f0ff02000180ff4b00f4bfffaf00f0ff120000b000c0fffebf0180fffbff02c0fe2f00300018000500001c000000fdafffdbfffabf00300010000400fdeffffbfffebffdaf0020000400fb2f00000000c00100000c000c000000000c00fcbf0080000000f4bf0400012000f8bf04c000000007000080000000f8bf0030ff2b000000fd2f00f0ff02c000b0fefbff0600064000300000000040005000fcbf04c0ffdbfff6bf024000b0ff02c0fdafff0b000400fd6f00000000c00100000000f7bffe6f00000003000180ffebff120002c0fedbfff6bf0340002000080000000000000800ff2f01100004000030006c000400020000300004000480000000f8bf03c0feebfffebf007000e0fff6bffcafff2b000c00fcefff4b000c000140000000040001c00020000800fe2f00fcff0a0000f0001000fcbffeefff5b00000000b000000018000030003c0000c000300020001000ff2f000c00000000000000000f000280014000000001c0ffebfff2bf02c0ff0b00100002400020000800fe2f002c0000c001c0ffcbff02c00500ff5b00000002800010000800003000300004000180010000ffbf0070000000030004c000f0ff060004c000a0ff06000040ffdbff12000240ff6b00080002c0ff7b000800024000b0fff6bffdaf0000002300090000fcff02c0000001e0ff1600000001500000c0fe2fffebfff2bf0700000000ffbf00c0ffdbff0e00ff6fff3b00fcbf02c0ffebfff6bf0180fffbfff2bf00b0ff0b00fcbf00300010000800fdefff3b0018000080fffbff0600003000100004000480ff3b001000034000f0ff0e000140ff3b00fcbfff6f0090fffebf
InRand = 20435d4bcb09f5a9b8188f056742ae4a0dbca938870e3bff327efb7662656001
OutPK = b5a0956984e94dcb5756f9ff394f581586c933aa95db66c5fbf68c15d5687bf954d27ba22042d62f8a6311571a81210da078cc70f7d411bf9c2e2c829c280e6ace7022f0de83c98cdf92a1f816a585080bb7fd5ace54adf4dd60b17fc35d3742beba77a10729f9c175954515474a1d7b1e0b06013cf2092d113461c99921ba2d84658c22713f530723f44642af1f8c87fb807a89d10c050635216259050061aa8f3c2d0e102e8e6d99024ac72120593f90d4982dbe5d130d004491ae8ae95afc12ba5059fe1d288a21f178854b50744a069617c70eca46447a189dfec5e7399dd90aac0a639485540bd060f96c877750aa13a118663f186b4a96e890d9d40cdaef268571012fd93fe26f689211a15eda78feafd1b97cc01590190589433d651cc73400bebe3b65aac4858d501e24a7535481ac5b996ad77a5ea814f16082705236299484b3d7dc8606de6e95445be4594e6030d945906b5660dc35fd753735a44a0874dead0ac44e23649c51f62daa013bfc33029ae994678da2ba46cac2a0bd283f4f48e7e9a619e9cc5214d2ea08e893c2e3cb9c11b287dc7835dc237a58c504139a9a49d11ff96c7d8215d3599abee62c54c407ebddde4f3c6b669ace8abaa61fe23b0ea98bae9e5599563c5263cd4125657c83f0d9a2c243158a7c2c6680a8a88add6bceb8e5e00f850394e69d3d47369dc9e1aa86b000d27f4a78c28c624506e8dcfe43a957497310711c54d3f8f22ce12e840a32d146715fc4c4039116a86ee7eb0af30db5adf7999c955a6a0067cc6c33fb8e3ab5124b18687464fc12177b69e66cae866fa291385b8ad872730294958e035a2a5fd9489acd5509a0005eab82dd177bb81af96c03b78d5e94692fb2357ff1bd2b663933b7d9646bc9eb4545fe970a886c54a9915a6c6083d47f42311d841874394963bf0459ebdb354785ae2babb696318ceceb28cd358ef9d389036cf5abfa814cb6abe1508261c9787dc44a9b4038b2a2585a125fb25bc46a179a8b47f1f841137b873101306a2556831bc110493d1c40c688227202c49ff290a0002ff0e56b859b3e3f46e0b34a2c44b19f17275a93257b7ad01640423c80431408813e3d6e5f94e7f18b1c22506c1c1bf4812a9b860b01b248805a03fd588ec54b1adb78a6c4f1af0c547c1b1f8257f6a28c11ea3972f860ff6a1ebd94202d1daaba1077512bf5f5ffb22c63dfbcf2ccba0d836c7042c330028b537364da743f5fec8b646c1974652e8e165c384da662acf28e51089a94857a024a5e6ea27f45abd0115b67d72460405e8ee1b00116ed26bf9c68092eaa8510c45f4015e920f6890a8b3a1aa64ddb820a2e5a6bee9eb399ca7d42a8e8ad79b9a1214e27f90b1f494c77a620f8158e0b6353999446c9b0401ef9910dce28ac6d6a6413fe8398c6dc7615ac85e4d470d1ed394d0bc1273b07f50bbfee2c136c2cbacf6e9e770fc02c9e96d9f39d601aa854e1b7f18a1b260f201055fc844d800af062b163ae176a5b72728acf030139c11d9e075f6cb0c362b00883fa9083f20649e28b75b7aead19e4b347a1e6111300da4487796df4dfdd16e242ac114d37f71485bbcd50f7047a92074265c450c78e016013ed25256a632b646a0840817083c5676182eabc595766d6f7b123c49acbdabbbe5ddb29fc83422432acc397241aeda878c6b6fab3210037d3b9f4a00d2e6753d5583961226bd16910590a7cc3993ff61156097f5bcffb4fae741f878572735296f904292bb9dd834a80fc0422bc002255f09377ce2dde000f23a4b1114de2aa9053a2495048cd9300b07ae6520ad9f2226ac813cbe77e8587d5436bba996042b41a6926a1e26019a34f88f8b285e2a2dc60061a45fb87d7892b745a4766f05a3eaa973e51fff6b7759aadea8254a94d12d7114ee265e96e108060c1fc82b0fea73ac320c9236d5768a979991d2f43b7d2bbe10f9361b959785958ead416b0433e90e757852865a292816d451a2a6a2dd8c87fd828f28de91f8a70cdf9164da8c74a939d6897db47449fe0b7bed448fbbd4d7a12444ae0e865b3f5af4ab8163db69a422c74f3ca71f8996c9758940e5edef168f9867a1f860c64e38508d0256b047c40181d4cd1f68fbdbbe44340fb944a67f310e15aeb8d6a3b168afa78ed81ca536d63b498a679556fa9fe5981c65c5b0566460009a557a7442da41e4cf5d7e1749ac929c84733ce73ca5e7393fd58bb07df14f861420a3aa3f6a1238d46b39742b490a54c8fa67cba2c26bbb655ecc2b2be47aad966b09b6580916f4a9ac3fe6d4e1bbb6161b81f0850bcaaf23c21a7239184b6f9198f9c16a1bd555165e25791e6951ec22acd97bcd10ded28ed67cac18a2f4164318c21088255bc3ad7612364cbaee41cfab0d8282033a8e0b18256c004eb0e6c5aec15854c456146591065664a928816fbfb213a5e4b4477148a2487aa5368b4dede4b54dad78566d42276558149302089bb23af8271e00090a33d29c090692da678a428442f35d8f0e6dbf40f
OutRec = 00000000000000038000200000000380002000080003400020000c000140003000000000400020000c0003c000000004000300003000040002000030000c00014000300004000280003000080002c00030000800038000200004000240002000000002c000000000000300003000000001c000000000000300001000000000c0002000080002800030000c000200001000040001c00000000c0002000000000c0003400030000c0001c00030000c00010000100008000340000000000002c0000000080000000020000c0002000010000400004000200004000200002000040002400000000800018000100000000240003000080000000030000c000380001000000001c00000000c000200002000040000400020000c0002c000000004000240002000080001400020000400038000200004000200000000040002c000100000000380000000000000000030000400004000200000000180003000040002c00000000c000380003000040001800010000c0000c0002000040003000020000c000080001000000002c00010000c0003000020000000024000300004000300002000080001800010000c0001000000000c0000c00000000c000340002000080001000030000c0002c000100008000280002000040001800020000c0000400010000800020000100008000280000000080000800000000c00008000200000000340000000080002000030000c00014000000004000340000000000003c000200000000040003000080002800010000c0000c00000000c000280002000000001400030000c000080001000080003400030000c0000c00000000400018000300000000080001000080003400030000c00018000200008000280003000040000c0001000040001c000000008000280000000080002800000000c000080002000000000c0002000040002000030000c000280001000040002800030000c000080000000080003800010000c0000c0000000000003000030000c000280001000000000400010000000000000100000000300000000080000000000000c00038000000000000200001000080000c000200004000380002000080003000020000c0003c00020000400038000000004000300001000000000000030000c0001c0003000040003000010000400024000300000000340003000040003c0002000040001c0002000080003c0000000040002c0000000080002400020000c0000c0000000000001c00010000c000200002000040000800010000800038000300004000240002000040000400020000000038000100004000080003000000002c00010000400000000200000000380001000080003c0000000000003c00020000800014000300004000200001000000000000020000c0000c0001000000003000010000c0001c0001000040001400010000c000240003000000000c00010000000014000300008000240001000040001400010000c0003c0003000000000000000000c0002c000100000000280002000040002400000000c0002c0001000040003400030000c0003400000000c000140002000000000c00020000000004000200008000180000000080000c00020000000000000300004000340000000000002800020000c000100001000040002800020000c0003000020000400000000200004000000000000000001400000000c0003c0003000000003800020000c0003c000200000000380002000040001c0000000040003c00020000c0002c0001000080003c0000000000000c0002000000000c0002000000001c000200008000380003000000003400000000c000140003000040000c00030000800014000200004000240001000080000c00030000c000100003000040001400020000c000180002000040003400000000c0003c0000000080003c00010000c0002000020000000030000000004000300003000000001c00000000800004000200000000200000000040000400000000c00028000300008000140003000040003c00030000c000240003000000003c00010000c0000400030000c0002c000200004000040000000040003800000000c0003c00010000c0002c0003000040001c00020000c0001c0000000080002000020000c00030000300004000380002000000000400030000c000140000000040001c0002000040000400000000c0001000010000c0003000000000400018000200004000240002000000000800020000c000240001000040002400020000400028000100008000080001000080003c00020000c0003800010000c0003800020000800000000200008000340002000000003800020000c0000c000200000000040000000040000800030000c000340002000040000000000000c0003400030000000018000100000000140001000000001000030000c00000000200004000300000000000003000000000800020000200000000000003000080003000030000000
Key = ad539b834982f525e844fbdf56fd496ca25cac45c6b5718de7f2417b7ff6e3b4
InNoiseS = b25e0026c0f1ac209932a42dac2b2a94f3d3a08078080b8ad39ddd85fe04106bad6c591655d7e6dc9936362a1442a112bfddef1594169d3b929b77663dae11971e713bb5d06882cc5933a4b55be9154f6b2da674e96cbc3ac56145875888931f64669d57c5637dbd469bd3b6504124227e5e86789b7403c7dcda60e2012bc20b28d116209cd9d26be498249ad7a933e63e587d4f8c8c728ef5a0e64fa532c8c56db5d629a803c451d0cabfa7fe185c559da2f73136b79418dd245cdd990fa948a7297591195b1fa8d6b953b3a4dc91692c84bada53c4ec8539394de26358102b509549a1dbaaa0ecd9a614b4e96f17d26ce3507c510d1798d11f218ce41a7900249e0ce70ca624560d0a74a23591f8fa553c1cda6b995c951ad4d965a8fea143523358b3147412422e629de92d64820fdb897a9ee22b5be0190e6ca889bf8b27914c61568bda84651b17a787d700aa1c8d0eed5b669d69b644b1283f61266f6d369a50f446e59c7bb911d1515023e484e7d949a9c6498368fd4291433629adfa93c993f5732e7e12a0cc3f79b94dbd84010f5711103f5d622fcbcbac55d511f8ba02ce47e00a4ec84d10af6684829275598c635defc620f59c5a1ce97399d12de74e9f84b8c25ccc87b4e4b7691d6cc595b40b6e7a2d0ea93773d60edb498ba0dc59906a930557d0529b4d975d68e1d0850f601b490f9a107847e909f8c8573c61927374d9a6bfac48f4ddedaeacc39c3037ecb7d251ebb98231bda7035ec9e2349ac3537496f609016d6a79d394ae43e951abe87fad7d7344148943fdb2b76b56c8e6316315a94eda5a3151a65e7608b80968442e33a7cfb1872ce5e2a1f462bd6d65c8d09a8023e944ccd88050a0c1d488843add51135b4ae73d90aef5143bf2016a668ccbfc6bc5d2275302ccb225a269dc08b26a83d96d16ab68e36eb19da009a87195e9200045d07172984ee427b983ec54af056df6caa32e24b2d579862ce60eac0a13a97da0312edf20d38cf94551a8fd61a78232b387a8b217f98ebb29737793d98a364c78a471dc04b0a3eb48cc9e43b6ae6d3875025d58e2aee7a95e69902f4c8bf34e73ce072572883aa930c1665055a07fec86c229dd9d5d4c8c80d227b278fadca1b00da0885b04c6959b96bedb6a5aeb5322a18cc116f29d3c1574cefd7513945479937a20040402011bacf9ddd010da0c7e19e8a65977d4bd96726951c18bd380c62e2fc861e338ab86587a69e49699c1587fc5737613405c50ca11a365b40ac58eb867f37d9aa61157621fb09737970451286e4e1e9d2cb01a1a0c1187bc491e2e1d75e08c02bcfe5cae870bd073ba05bf2b2f4be0d61a4b461970a5d930b5c9bf111b11252e61d3f4a7bd549ec44c0beff42a9c6273b03cad315907f490808144904388d4760e446e6bdadab21593a363f2db448987425f6963012e2803a4c50500ca9a1f22f9d8b64a4c59545bcba76813b7d41fa40d741ffa0d1ef60a040b4441951245c1b4aad9af707c1815959d0bd0bcceb80cce721b83ad1cdb9c1d5b45ae816403d63794cd285f169ec609791aa24f82d58e04436ec63d4a6086803ba584c83446519207c072d24a6ec7a696625e1cbff76c54468e458190e28e6848a4b6a52ab867fb9c0ec845bd26927d1d8b9f24f7afdc72402e65a1e0de44f45eec51585c594eebfee849f63ddc54ce073081837945a121f92e02f104c386df92b927ad02aba9ccbc2857f2557c7aae8eaf8524cae5620d86a2ebe43e40b108ea592b5450f10fcff13bf068771cc7440e7d6ae66c9af4a3340b6fcabee9ef459d8f8dd4b804717b3ec54ae2246abb7a2bd5647712a1694262eb4886befb8a11d4fd297f512e18b819121f4de1af51036a64fb97a111385d7a218ba794b9ddb7066fce7bb3f1b86590b7eb1b753a29d3bc584ecd300fdb33db715c5a15cc1bc3f2fa49a9abc52815c464af878781e85e15fee92788950005deae6822e084a4c9cbdae862c58f76a6fd25262a3a42004881a7160bf546e066f376163ee028b587014a2b2b269a19dea85c4a7690f3d2065dcb200af1e6714199d7498f3858e61d0d11e8bdaa85288c256cb8bab2982e038a084f459ba0697e7e9159ca0de7b2ecab32a8a0e2b3e26097e321868aedb9318c7972bf6e011e03db452ef8a07ce49d129d12b7e55818e9c4ada4dad00e8722764009ec09082a7870402abd180d050dab6cc5e110a290db641ae620ed5ec58a7f97821e07cb54de427454a5d90d28926af2008525d9f053487aea87972764023751e5cc959a793aa986230814082e8d0747d908027b0e0baf36e8768776a79a7056b438b8a7d3a134da4b698c8dfad12e418b2435f4aeda6cf0a6d4d4906e3d4845606947f87963c7238592e81aca8b03405365408383d120fc3178696d6599ca124fc6014ec6f2e93d274a8e28e3c64a395e433043283d81a91839d8984f642fa1c1043932596fade0cb561e08cffb08af0861535276d622b225d38c755b969c1971e24d600a9a5c
InPK = b5a0956984e94dcb5756f9ff394f581586c933aa95db66c5fbf68c15d5687bf954d27ba22042d62f8a6311571a81210da078cc70f7d411bf9c2e2c829c280e6ace7022f0de83c98cdf92a1f816a585080bb7fd5ace54adf4dd60b17fc35d3742beba77a10729f9c175954515474a1d7b1e0b06013cf2092d113461c99921ba2d84658c22713f530723f44642af1f8c87fb807a89d10c050635216259050061aa8f3c2d0e102e8e6d99024ac72120593f90d4982dbe5d130d004491ae8ae95afc12ba5059fe1d288a21f178854b50744a069617c70eca46447a189dfec5e7399dd90aac0a639485540bd060f96c877750aa13a118663f186b4a96e890d9d40cdaef268571012fd93fe26f689211a15eda78feafd1b97cc01590190589433d651cc73400bebe3b65aac4858d501e24a7535481ac5b996ad77a5ea814f16082705236299484b3d7dc8606de6e95445be4594e6030d945906b5660dc35fd753735a44a0874dead0ac44e23649c51f62daa013bfc33029ae994678da2ba46cac2a0bd283f4f48e7e9a619e9cc5214d2ea08e893c2e3cb9c11b287dc7835dc237a58c504139a9a49d11ff96c7d8215d3599abee62c54c407ebddde4f3c6b669ace8abaa61fe23b0ea98bae9e5599563c5263cd4125657c83f0d9a2c243158a7c2c6680a8a88add6bceb8e5e00f850394e69d3d47369dc9e1aa86b000d27f4a78c28c624506e8dcfe43a957497310711c54d3f8f22ce12e840a32d146715fc4c4039116a86ee7eb0af30db5adf7999c955a6a0067cc6c33fb8e3ab5124b18687464fc12177b69e66cae866fa291385b8ad872730294958e035a2a5fd9489acd5509a0005eab82dd177bb81af96c03b78d5e94692fb2357ff1bd2b663933b7d9646bc9eb4545fe970a886c54a9915a6c6083d47f42311d841874394963bf0459ebdb354785ae2babb696318ceceb28cd358ef9d389036cf5abfa814cb6abe1508261c9787dc44a9b4038b2a2585a125fb25bc46a179a8b47f1f841137b873101306a2556831bc110493d1c40c688227202c49ff290a0002ff0e56b859b3e3f46e0b34a2c44b19f17275a93257b7ad01640423c80431408813e3d6e5f94e7f18b1c22506c1c1bf4812a9b860b01b248805a03fd588ec54b1adb78a6c4f1af0c547c1b1f8257f6a28c11ea3972f860ff6a1ebd94202d1daaba1077512bf5f5ffb22c63dfbcf2ccba0d836c7042c330028b537364da743f5fec8b646c1974652e8e165c384da662acf28e51089a94857a024a5e6ea27f45abd0115b67d72460405e8ee1b00116ed26bf9c68092eaa8510c45f4015e920f6890a8b3a1aa64ddb820a2e5a6bee9eb399ca7d42a8e8ad79b9a1214e27f90b1f494c77a620f8158e0b6353999446c9b0401ef9910dce28ac6d6a6413fe8398c6dc7615ac85e4d470d1ed394d0bc1273b07f50bbfee2c136c2cbacf6e9e770fc02c9e96d9f39d601aa854e1b7f18a1b260f201055fc844d800af062b163ae176a5b72728acf030139c11d9e075f6cb0c362b00883fa9083f20649e28b75b7aead19e4b347a1e6111300da4487796df4dfdd16e242ac114d37f71485bbcd50f7047a92074265c450c78e016013ed25256a632b646a0840817083c5676182eabc595766d6f7b123c49acbdabbbe5ddb29fc83422432acc397241aeda878c6b6fab3210037d3b9f4a00d2e6753d5583961226bd16910590a7cc3993ff61156097f5bcffb4fae741f878572735296f904292bb9dd834a80fc0422bc002255f09377ce2dde000f23a4b1114de2aa9053a2495048cd9300b07ae6520ad9f2226ac813cbe77e8587d5436bba996042b41a6926a1e26019a34f88f8b285e2a2dc60061a45fb87d7892b745a4766f05a3eaa973e51fff6b7759aadea8254a94d12d7114ee265e96e108060c1fc82b0fea73ac320c9236d5768a979991d2f43b7d2bbe10f9361b959785958ead416b0433e90e757852865a292816d451a2a6a2dd8c87fd828f28de91f8a70cdf9164da8c74a939d6897db47449fe0b7bed448fbbd4d7a12444ae0e865b3f5af4ab8163db69a422c74f3ca71f8996c9758940e5edef168f9867a1f860c64e38508d0256b047c40181d4cd1f68fbdbbe44340fb944a67f310e15aeb8d6a3b168afa78ed81ca536d63b498a679556fa9fe5981c65c5b0566460009a557a7442da41e4cf5d7e1749ac929c84733ce73ca5e7393fd58bb07df14f861420a3aa3f6a1238d46b39742b490a54c8fa67cba2c26bbb655ecc2b2be47aad966b09b6580916f4a9ac3fe6d4e1bbb6161b81f0850bcaaf23c21a7239184b6f9198f9c16a1bd555165e25791e6951ec22acd97bcd10ded28ed67cac18a2f4164318c21088255bc3ad7612364cbaee41cfab0d8282033a8e0b18256c004eb0e6c5aec15854c456146591065664a928816fbfb213a5e4b4477148a2487aa5368b4dede4b54dad78566d42276558149302089bb23af8271e00090a33d29c090692da678a428442f35d8f0e6dbf40f
InRec = 00000000000000038000200000000380002000080003400020000c000140003000000000400020000c0003c000000004000300003000040002000030000c00014000300004000280003000080002c00030000800038000200004000240002000000002c000000000000300003000000001c000000000000300001000000000c0002000080002800030000c000200001000040001c00000000c0002000000000c0003400030000c0001c00030000c00010000100008000340000000000002c0000000080000000020000c0002000010000400004000200004000200002000040002400000000800018000100000000240003000080000000030000c000380001000000001c00000000c000200002000040000400020000c0002c000000004000240002000080001400020000400038000200004000200000000040002c000100000000380000000000000000030000400004000200000000180003000040002c00000000c000380003000040001800010000c0000c0002000040003000020000c000080001000000002c00010000c0003000020000000024000300004000300002000080001800010000c0001000000000c0000c00000000c000340002000080001000030000c0002c000100008000280002000040001800020000c0000400010000800020000100008000280000000080000800000000c00008000200000000340000000080002000030000c00014000000004000340000000000003c000200000000040003000080002800010000c0000c00000000c000280002000000001400030000c000080001000080003400030000c0000c00000000400018000300000000080001000080003400030000c00018000200008000280003000040000c0001000040001c000000008000280000000080002800000000c000080002000000000c0002000040002000030000c000280001000040002800030000c000080000000080003800010000c0000c0000000000003000030000c000280001000000000400010000000000000100000000300000000080000000000000c00038000000000000200001000080000c000200004000380002000080003000020000c0003c00020000400038000000004000300001000000000000030000c0001c0003000040003000010000400024000300000000340003000040003c0002000040001c0002000080003c0000000040002c0000000080002400020000c0000c0000000000001c00010000c000200002000040000800010000800038000300004000240002000040000400020000000038000100004000080003000000002c00010000400000000200000000380001000080003c0000000000003c00020000800014000300004000200001000000000000020000c0000c0001000000003000010000c0001c0001000040001400010000c000240003000000000c00010000000014000300008000240001000040001400010000c0003c0003000000000000000000c0002c000100000000280002000040002400000000c0002c0001000040003400030000c0003400000000c000140002000000000c00020000000004000200008000180000000080000c00020000000000000300004000340000000000002800020000c000100001000040002800020000c0003000020000400000000200004000000000000000001400000000c0003c0003000000003800020000c0003c000200000000380002000040001c0000000040003c00020000c0002c0001000080003c0000000000000c0002000000000c0002000000001c000200008000380003000000003400000000c000140003000040000c00030000800014000200004000240001000080000c00030000c000100003000040001400020000c000180002000040003400000000c0003c0000000080003c00010000c0002000020000000030000000004000300003000000001c00000000800004000200000000200000000040000400000000c00028000300008000140003000040003c00030000c000240003000000003c00010000c0000400030000c0002c000200004000040000000040003800000000c0003c00010000c0002c0003000040001c00020000c0001c0000000080002000020000c00030000300004000380002000000000400030000c000140000000040001c0002000040000400000000c0001000010000c0003000000000400018000200004000240002000000000800020000c000240001000040002400020000400028000100008000080001000080003c00020000c0003800010000c0003800020000800000000200008000340002000000003800020000c0000c000200000000040000000040000800030000c000340002000040000000000000c0003400030000000018000100000000140001000000001000030000c00000000200004000300000000000003000000000800020000200000000000003000080003000030000000
Key = ad539b834982f525e844fbdf56fd496ca25cac45c6b5718de7f2417b7ff6e3b4
InRandA = c664383843e8befe514ab2bda15c5aad395931045b4b1c235b7bca75ad04216935f18f64dbf1d22c2e410c50e84468859fa80efbd78b1ab2cfcba7f235b471e5107e3337aa4de117333b3de593075f083a31f22e59964846dd454df9d992372561218a20d1f59a6628c65bf060d7a6956e0bc2e679c6b85b44ee1b07a13faedcde44724d4c98ef58516be8346ea4422008e96d68225fc9e0eebd5d8e149956cd1660c5eaab33387c6c17774073e9516009a007de75172991609901deb2808a3b93a15cae615e19852ab9a8fc415ce6f2ed203fc1f785ef6e77739d44eab1720ada4a7ad43cd96b99ad29b15c80b42f0566315841035e246e6b2358372c5257a4b97c3bf6dce693cf5c3f8acf468ac9ee2903a075eb829d9506e0b21504699f7cd7dbd72cbe0a36cc7e6b47f28a00e5e2a848bd95bbcaa9e14f9a72cc9edd253a61419e24dda294fe0de54df1fb14227b73d7cefad3bcbbcd41e74199797eab8089e7e56990f86eed4a3c8c7f39df1a70aaee6fd429d39854286e52d1bd8a0c2a8403ea58b010f0a175d0a974365a2558446b3522186cc2e0ff1b604caf2b211eb080f507ded619594de87d7f2655a2ea918dc384394a362a5a985c6bb935c14100acca189e84494ba27373ab1e955b228122807d78f1cb4a44b64459c90921308a448a83e14556129464459e9204cb2a90e3295833701d0bb6e700d9b3ed30f9599a31d6e00d871bfdf7e3e5a4e2a4317b233e4cded198074395092d9c9c513fd295e71cf4e0e85e2989eb4a31c752b5791c66842db51e4e8e150b23ad4c5724bff7a4f9061e5ae5c91a69615aa36fe6eb044b374fd2b88d5a532c608c8aacb091d08cea8a67a9028e620d7b41047d7a88d07b39050aaa67703101a492be1cc1f16224a91c9ce75b5e48ac5389aec2c7fd44b3521656a38e849b52d7c1dbd9138f868f78cb405c830a00a60f0e6a814efd8599726fe913b7b4fb36b2a94eacb7d938a1212d5f2aca551a2166f32ae45c2933ed945476014151448f649eca8b1b2b07c181e9153f4d7c78eea1b4ee00c4316fd073a1c9da8bbc2876f256e3d2218a180b2efc04fdfe61d2c417093e483bb0535a6892d52515ddbdeab4544b8b45e945650873f24025a6a65c3fc2202a244c695acd60f555f8b5ba196336daafd899ea09f1a8df918277889118383c12e5a8dda938ba5d0214148a16daaf196b6f12a20d17a6d1b57882b4437d9f0099cc483e731fabd2151e4febef2d55bb881f271a343306345096e8c4658a583cf2682d41ea924504ad0069c1764a5fc2c959a14d93ecadc18635e476b7d639d2bb008fb1e05ab6e454a30143f859f43477e7cc6253df152e2fa42958d67446dc9843c42e294b6196eb17c928811c0f686902d52cc24652e43344a6da135f6b2df84b4a802f703965274f8d5566469d9a146a65978d1d453f581881a52680f3eb9a89677563082bbd312bf53a569dc5c6f1c13279de627120fe804f6305a897fe479b1a5729836db61c9bf9c3cc96b9eb52a4836ce0608be6be33f1d2355bd45be2449d10e4012e3a92e420531056ea532039f8ca2daad8d0051d5b201b262db64e0c60901ae91d22126ce3390692a61b6e13d9a4b6ec44019a08e9241ca5e0d261baa092161eb58fed33f94e91a2bc18b7d1dfddc122de3c8d93bd6619945987c8af349714109a65b3a0f9a946b8843b1677d867aa8c5b38a1324d4a5cffb8d98e94e4d837b16c0a823f04ea17d4f470f7c46cb49d01ba23e66f966f111a525e662a0b69818801b8c4c7398f21954168551580766d4882b0f6586f4ace742d2c07b96dba61dfc8763aac92289e84afb1ae4afa784204e82f2c2461bc073da91c3615ca970f195e37b9e5a11143e1317336b320d349b6402979cc6fa1984a843cbf1435a519ca957fcf45658ddaaa8fc130e1bd3ebe5c8b4164fe6a0b76d6e3f252d170889572babe5085a68fb42bfbf45a9419372a7e926fc604faab4ce138d34a1e6438c649ad282d4077ed990b911656c6192cad9a079764f995179eb3225fc67fa71b008aa1a4821a991133497e28cfe02ca4a87cb087c412a8998d22fb4e807bb51ebfab53a6c9a6602e9cc54f1a8f9c53ef95c5f0879256b1d6fe2aacfd488943a49135d49fc54fd326e5963ccc451583030dadf30086128bee2b74902c58d9c0b4a10bce90a3848b75d4751038dd3ae5827f95a83476e060f38779d151a8deb0517b6a526415447b48f66ce28615a5e3c10f971397375a7c0ac5264266f4b930c34faba354d29f795c9aca392413586218e567d9bdb95209c94322a1d96c9a628f9e97abaaf6332e4e61ed0d904b119086ed021401be72abd6c460d50dd2a7d29ab890528d31070b7d781f2a6912074bd1fde427f60faab61b263c2d52cf6a4092b66e9080617554aeda564da0f5c9586c987541ec2551a7ca0d512bee052be4fef66f750b7c9bda78350ca4812394545041af7d550d7142e579db6d954489301dc4cd9b405f685d69470c325c490b
InNoiseS = 8159e4d8f3901f0cec2355ebc6511fa4993a1576af5257b606f5b5317703e6b78b4053961048db1d4661b68e7bd70c8a00f758c257fbb81ed7cc2aba5fb098a4a0e8d5b5466ad209a639d99c0408eaef04895cae0cc75a18838a2d4517b927807d1e83ef9dd6f1cc1d42ca623b720581b804bee5b95ea47f8a7440db5073166fc595b314a519c178bb37b14b7b18cbe4d68027c45acb6760ed815f035b7b108c4193e470611f2e413d50e7d0596537cfa86cb93c4400c8240978a9d2325f0d30776de50e351662f2d97c8878468dfa5555618c0e25e237fe268658069153d90ee7552296b0853f2e2787853e2a72accf3dda02b203bca258b231b8b60f5fc0aa02b5680b15d6122e8d8bf5a7c474fb867d4f9840a47a198ba81e0d20b55692c528f0d296aa6ddb0a0e868fe41c00c01ba21900740a9cb3469e0948774fd769215a2b8ce940f37ed2b3e989c1883c548a220b88020dad389e55175989f916e62edf3bfdb9569ba33f8242a19e1c58141966be01e50c9514179644bfe6e2b0352d6d17eb637a498a5fb0d57181eb5400260ca0737e59038053a543cec243ee1da72263a0bd3669d4198b62855aaa315a7254603326e4a209116ba66bf9e7abfd34619adbf4086528fb24ab9780e54690695646eacdbb7e2f111782e11001464c22e74e52ddcba7a653bc822f6aec2ac0b694c9809d21de4e404e086cb67e7164b5018d29c3f64da96c1e7291949028ee6d279fa4314b26dc4515f95cd8436dc61a1c0dd429fe3652c8048c09392999b93b96de1be819e833d40b9f20440132d94b2cd13789473b5b87b41c75a3a5da6d8880013d8246ead4983d33c21e1ca7a6ac45e60c0e536ccd348821ce5bf59829bbc8a6357b5839cbe6d9a47bae4bec2963a023766b7d835f21d25c0bcf43b064400969a5ec08a50d245954e8c433bfc06347df623aaf988b17680fe0709012dbe9f3a071f92919de80f6825284a35929619732367a166b065ec83f9fe53510c0b84714db410b391ea1851d1313af396d8112b1c608300123d8d1c47df0bae78f97ca03f988d3ef3697aa76a11ba72e013d316a83edce235e680d8da0e6009dd019f6652ee8111419ed60586a116a637c9d2fb8ddea48384945337cc9720b63f6f7af590e4410d7a6be0c4bdce16776e0385ae3536a81104920c449298a8a0269c2d731a1b561a4e302358445cd1647abb5e54f96b07982e60a5d6200b9070949e6f974771cb9e3080d4bec507e3b462e8fe72228656201828f98d31b736e6dd0de704501dd3e069e7a070ae89c2e66ffbaae926426ae8d507f469b348f0996fa70274a90aeeb22ae51f11365123d7aa93ba0f309ea161f66cad5ca3795563fdcd0717d8650cfcf49821f5a600444b067f7d9a9619f2da086d1877dea143a77097e6999612155e9544a4c88a682e5014a8086c18a6e88942bc38254ca4c3021641b434623a046138b9166039e46e52bc2654f52cc367917fcaa77c7ddf798e6930f6cff97d8305c5f1323047f826279a115abf31470bb6868a4cc9a1f099246758a9801b769ccf145809e4b0d77abd4997d1bc88d90cd1a26ae6383fbd7d2aa3026ef860f9624ad092839b7d5753f1e266ac02614e1dc23052bf8171268aa8ae6c67105a38a08cfd93d7a0a35f5071104f7820632c760756ec263784676aaf708d6699fe09534dc1865cd11b1a58c190a20d93e33204475daa45f7c11e61900754ba3e93827fe2a2212a0f9839c22924ae69102f1ca4c1e1b8125df684cbd1839541b856d75825dd24a1a615810541348020f56952d89435c006d4aeb365ee11ac9a14709c8a894642265d03022243bcef2826f94227d02a1e6851c98c124162681a5113eddd24b3d889b58c0fe2a396a67b8a952b627c20ce5c0d8d66985261ad13b7658ad0b36ce4e24435809b928dc229dadbefccced1746a616d8d202037160442edde9e0f730542355d9cbe81433ef1e8714276dafb05671149c9a77e69195856e9e315820ab07cf35492a0b8009bb7c913ccf34ab5589ad0d6d7b6840b9673945ba16667a03cfcd70a70d14718c5b228566b54fa15fd1100a7e7406d72c6494e14643030d35a44d93325a07083cad85ac1f51d05542402eed5bf08e4e1046c3b4607ff864e4681581376db62ba977815e28203e066702c911593ead01d6ac4c4a69505e56ce6d59ae149631dcf19c2b0d8f05846a9a33901cf078fa35aa5d3f67d52649769daa605282581dd8f4c0f6156b2208841bd3c1573b42fab7c74db0aa0f4f5927e24765d83a307b644700704bc0bca665e1a8c240a9e4296d0873a6041d18f9633738402682fc23752931c611b3e526f2d43d95a346da7835e0662a68daf4de5e2c7561b1b9e2a836144be8841e157f62e22aa0293cb07183e0b9e4b6bfcf6b7baa91353264ad91795e2458125d441a4fb04ec0245282a18abbb39f6bd6c695b392d7ea22499eb22c5a795223191848d46f5691615b274ef72bf28d4226928947cbdcb02a0bd8e28ed45a
InNoiseE = fbc6ff58a75dbc6e5cf3845afc27d2e024f3012cb691484ec86571bcd098636a008285835cfb3353942b9ba32e97ef3e1e17d72cb53cc5aaaad50235ee2ebe324a50b911963da9db2df069fa3a9905cdc54f0a8e5defcb69d08447df66b34244b4b879a6a577ff1a473c00b08b6eaabdddce9214d64628b053bd47633e215fc5f28a3bb10c115dabb2561d818b0147f5bfdab802decb987d7cb6c503a55104965b5fded9cb1d8c7faf557edac6c45acacf2f91d7debde409fd0b583060e581e7c50542b528099b192cbcb220254e17959933cdd481f944e99a8f9b0736dc9a661540f2e11c503f3614d873e4929b5668be71c9291f2f4da753747a23fa49c139127202ad96ce29e3a247cb638d97c40967cbd1b1a0e1ce6420135f8907a5485c505c73946046add0ca78491c934fa7851acb4e857110b4dabc1da28382ca03f59d69906941829b2d2d72ce99731f108f78cb3956096911cb5f98e8a8a5a109a2acb22bce952721a6d47844183e0f8ae14b5914de6c82a8b821a96243d9cbb7404308abac47904a0ce596f6250ad299fbe8a546482c7afcdbd745b942814e8d7b5087113d5885ceaab6c1893e166bb447f0079b1746ba97d95de7cfbb09c2f884be4927369cedbf8a4e0140d3e4409324cb5ae536356467bf09ac6e2f2a483451f406093a8943d56cb8302e9f898abeea41490b42b9b6e086d088362105a5bfb7605a22a77c5947ec2bb07cec320523899b3c29aa5e146b064f3e959340f1c51e380e1f94ce13f25c568865ae7a1dbdac6d526db2cfa44a732853a2dfb90df51bb0147e257557901a3474f863e6c100086d3034055b596ac2debc72a9f1376ff536facc099aa88cb2968c5beaa4f48bc099ccd6b5f8b33b047997689c6a1b9bd48a2e893c2c5cda755759840ca8e227f9224c74ab6e881a841528c7f0086bad9af2d82375aae2809cd5b4f665a445c4cd2daa50d146c983ecd2e19d8eaf85d24321163b921869807e255a4da5a5800b51a84a0f7cd447587fb66e3f94f7f08359233676ba7d8e44406e7a593549b2c5a72148256c3490c65af28846eca88c2529018c1d0517557aca9d9a4f35eb35a5345f2e3caa0ec9602ee97dc18c049d1045603543c404b82424dab739a2a42be4c8f4d83442c3ae80b91425d22a4113bee47a61dbe74bdece5d302dc2459be992c840d0d6398068d3c0ce578d997168d81d1302e86c7843d93419483d90e7da02d97536ad0ca827ffc8bc5ad761c4da16bfcd866b103faa4040196c383f11822bc865e6288d27e98759da788a46c827a2f3662a205f98be55422c172c4fc2eaca3a8fa911e7ab157284141365170ea02c0461c7d000c11f781175a54f92694e8716f2089aa85c1df74bf8a547bf991454c13ab7d81dbe02e2cc4ea953d7849d59a649120c1a630c4b57d4f5e67ff67560c93266453e12cf2234ab34a90531c4fd86764d847addbd6921be4ba167534390808d742dd282c88a926fc21ec6e8b059b65e3bc8c4dc738425ef9a0ba10e681b1ed8ffde75b04f955bd3358f741c5be06bd69b222d00615a05006def7e01ef5992bf93209945ae13d6ee6f44a1c16340181688724e357669d6b04f61bad76742268c389a36cebbe609294729e4e364147c6204d2e7f6b1954a92172a10cbca1f47e0dce19e356d4a0521830f504058c6d035b471bbfd9bd3db70a87f621b59ea115e5d1b028cbb66288b49cd48b567611602931697117c94c65f51a07e700bcfd60ed54ebe18ef0a72f2e9fc293da7f332c709996d66d8e4b785a2e6199c08368d2e028e023686a933f6dbbea656990886e8eb9931bcbc16da0950498c0dfb43655689ee3794013a69e0ca65c3a5e1c4923db71ce7b6693048a9fecd8895ca310fa1d93fcac2093169c7e458714a2eb1ae319241c88b491b75f4ac567f40211eb68dd6adca53a368ef2e6c0b89570821ba5d9805bcc1fd141a8385e7884e65af2852f9411f01105068fd41605572f0cac986688a42bfa5c7472fc17c220e594b7194698cc87b4788c831df1afab81952295a631449c7696b66aa35e82c34466a5625b1d3584492ac15a05cd2abe26fcd647c526a226743fa7aec6e5ed90255aff582be19b80730550fb8e3a8218d924c5dda52b5f7cd6ba049192244b43c01eb98f7650e3fb99581892b50601282c2b085ec858c1fc90b0c7eb1a72557bace0eb536a42f3310a29e08cd84b3993895decad42bc1701fe8629464de55037d60e2d3f0c57fb98dc1f5533ab708a950020bae7aba840d7a7cc1bea74c37da9d3e767951d4c9a405a1410f1334c3bc058ca75052c17110b2e025f7323a66add069f0539d0b9edbf548d7c110de42c4b4ee194dd76ddc2b2dd6a577437f927cd6a80e57acc6e752beb1c9e6f39529966397deeaa7e956f39f9de62ec00bd2129eb6bae6877824e11565bd6c8f0773796de4acab01ce8acce5a44ed9a74827088e8990cdaa56c264751581d37555befd6e2db56df5a43943ed285186161729dc14804082
OutPK = 3821857b649a3bd42b7258662d639824e8b22c7661d9e7be58001824e56bf942c51a7aa4cf2e064a7e0938df4aa774554d9023d7887196425a41d0ca79b166690154c32dc59e580675dba22a63a76894a216f96241a7391a9a3db565e906077c040ee29297a2cac16159cf7e0822c097ce2c47556eb807e109fa6adf886b3222213a159507d209d494aa2042d2af1ac8933cb573e26819f05c36468e33f0eab26466c0fb0735cdb97f6270f80dce78721c73c4bb840cc6c8475b1c8d83792498dac8353c30eb41e5bc1419fb8a4f11384431e0c4ab597a3d68b6eed71ba66a21d8d714d77d7e4c7d1fd994ae407d38c3f631631a1ee7a3872b4da184cc02f5f947d2ae8d96740a1f2840eeabb1e0890e42828a0da52b15679de6a7f519b5b6d60e808b1819861c0cb87401a47d4f27475510d9b67be9de19814c0c6cedf2b254190147ee115b97454401de4a0621fe5f4e544a29f2962a814c2991099207042552388145837886ff93c9ca76cca1ecb05eac9a45cc5f4861909596ad55d9d5d627972cb35b1b9941e6281bf29cf9a9f1cc2298605914ad858daaada41a9a0dbd16985abc8b22c064690ca2ed022ed847bd1daa98a76876368277c82921ce15a1916d1ba1b05a86a8cf6600041567049d51a9c416a5314b13a8ce753eba167ff497d08209509bf4206cad3f852a03c54d31d5dd5e37d13e96666ba9f3ebdd8bd7c5e851f73cbac90258a90bb91bde8e7d003b0c2b2786c966d6706e4adb3a81e4b1803c99a00bd94d45cb0c4307ecb9a42f9dae935a226e84472ad76ac59fbc5dfd662c7e917000d7a901d427490bb0f0555d59e39c4864a0c62a2dee0dc2b6a856695c8e90a34981e38d2239da79a853c979e7bc5146fc23ce8b945e15290f525932f409cd97ee41d4a0ba6bca6485e95d476fabebb320ea2b639a16d8cbdc6a55d72557f7509f9a26ad3053165b7ae23a652796270fa783d417e07376d41966ec36102b6bb175c2cd20ea5abf92366468c74e0196afce0f23579bb4575c235651ff10ab3a4f38813bc200de7e262e11ca31e8854f85c858bbb98fc16f60e730d2b817489699768a7dff031036894c39ed99c2818cfc85ac51e1617b8e7bfd9f7540c0e938798bc539b1509a10e2bae74d0a5f998e2c83a53a3b8c94bf65b96c98c4eff216d1f93593654844b6f0af158d032bbe86196541d6d466c2887cc874d2cb75bc06a68585dd0a96d4de25c21ff64d7c0c20716032981a23acbbfc6980fb6a8b53475d644640efa7eaf65a830e95f97bb97ada61b2a14bfa13f7dc4c4a26b53541c53f51c9319f272e36e4b9d855bb09277aea1693c6e82c27bd85509751af4a21b0595c2ab164b79176d2269cf7903e996ccdd4724148a0ebc47531d04881ef562769420596891717778968107c9a63c86d491ac5dd885b672908e7820a419118633896d67a3274455f16acf436bc838a2cfcc5dd8503a982101488457d63043cf83bb273abdf0daafc5d966029fdc9235a9df74d024aebf08b4a9aee68f2b16185ceeb73a4394f015263771fda7979d947e84c616f380a87935ab90f0d9afcd79a6aad65efe6893ca21016915ef66b26aac818ba75a9985045d8ab749bd4a6ac8e2512febc2827e18965e37c9467982f0ab6a57cf70056981d4810f7e21158ada05fe354c5f3b1926802a7a3f88c411c2d01d9e56c2263bc64cf3805f0767b5f199b3d6535d3002b244ee2b0974acaebe9aa155ea9ee9b021d473f8cc545e45e227e8ebd5b4542b527ea5b4262a04f8169ba78586a830cc649d2b78e6f726da1b8e56db1f5e01a48bc3a379967a9772796450fe5f3863da94cef9671f4f56a3461239c3579ce7d2d6194cb84504a7a9cfe00f96e29d1ab69313bf95c021801f0507c1801081484682a15b241f8e7f345517ded639390958b448869ebb50087482f26fb8c7d7aca0f6720ae0d59f21e22e1ea66af51800fe717f444d9ea224216460a2e92f09aa3298879d388d8f2540dcfe5e617190e26fa6e87b9c91685a1131a5a14323bcde0be36d78510872b79a17745733311236875c827ca094f0ac6e5917d9bd6d0e3cd2194cf79e39be41b8dacf804447a44c6862571f0f496d9c8a8e549619b2b2f8af4d116a195cc1a34571a41a62fa09adec4744cdbe505f289047302a820a1a03ea9a2b6e9793d8a9b90b962b96e205d684161918194e1c085db26d812908ec429c199527d2b7d03e6b40fdf551cb70aa0a7a224b3c01bbe95762ce941d0ac72a1c0394acc994b1424985bbd6d64ec119cc535a00c229f37f7c21e32e92b9d71eeb88a118015b454ae4a0bc23bc8daf5b589628dd23dbca40966e0a7cc1463758abbd7ebb260da1dbe944df451fb5cd5f1437467d408509b5d5e726f265d93801155f282f73998f653e643c4493d70125f2c006b402eae4629efa69aac7ba8e8dc04b67009da88f6d8dbf148874cf4733845895ae13fa21746aa899b138b30b034d5e733380f66301dd129e030d43197c1b7f373d126
InPK = 3821857b649a3bd42b7258662d639824e8b22c7661d9e7be58001824e56bf942c51a7aa4cf2e064a7e0938df4aa774554d9023d7887196425a41d0ca79b166690154c32dc59e580675dba22a63a76894a216f96241a7391a9a3db565e906077c040ee29297a2cac16159cf7e0822c097ce2c47556eb807e109fa6adf886b3222213a159507d209d494aa2042d2af1ac8933cb573e26819f05c36468e33f0eab26466c0fb0735cdb97f6270f80dce78721c73c4bb840cc6c8475b1c8d83792498dac8353c30eb41e5bc1419fb8a4f11384431e0c4ab597a3d68b6eed71ba66a21d8d714d77d7e4c7d1fd994ae407d38c3f631631a1ee7a3872b4da184cc02f5f947d2ae8d96740a1f2840eeabb1e0890e42828a0da52b15679de6a7f519b5b6d60e808b1819861c0cb87401a47d4f27475510d9b67be9de19814c0c6cedf2b254190147ee115b97454401de4a0621fe5f4e544a29f2962a814c2991099207042552388145837886ff93c9ca76cca1ecb05eac9a45cc5f4861909596ad55d9d5d627972cb35b1b9941e6281bf29cf9a9f1cc2298605914ad858daaada41a9a0dbd16985abc8b22c064690ca2ed022ed847bd1daa98a76876368277c82921ce15a1916d1ba1b05a86a8cf6600041567049d51a9c416a5314b13a8ce753eba167ff497d08209509bf4206cad3f852a03c54d31d5dd5e37d13e96666ba9f3ebdd8bd7c5e851f73cbac90258a90bb91bde8e7d003b0c2b2786c966d6706e4adb3a81e4b1803c99a00bd94d45cb0c4307ecb9a42f9dae935a226e84472ad76ac59fbc5dfd662c7e917000d7a901d427490bb0f0555d59e39c4864a0c62a2dee0dc2b6a856695c8e90a34981e38d2239da79a853c979e7bc5146fc23ce8b945e15290f525932f409cd97ee41d4a0ba6bca6485e95d476fabebb320ea2b639a16d8cbdc6a55d72557f7509f9a26ad3053165b7ae23a652796270fa783d417e07376d41966ec36102b6bb175c2cd20ea5abf92366468c74e0196afce0f23579bb4575c235651ff10ab3a4f38813bc200de7e262e11ca31e8854f85c858bbb98fc16f60e730d2b817489699768a7dff031036894c39ed99c2818cfc85ac51e1617b8e7bfd9f7540c0e938798bc539b1509a10e2bae74d0a5f998e2c83a53a3b8c94bf65b96c98c4eff216d1f93593654844b6f0af158d032bbe86196541d6d466c2887cc874d2cb75bc06a68585dd0a96d4de25c21ff64d7c0c20716032981a23acbbfc6980fb6a8b53475d644640efa7eaf65a830e95f97bb97ada61b2a14bfa13f7dc4c4a26b53541c53f51c9319f272e36e4b9d855bb09277aea1693c6e82c27bd85509751af4a21b0595c2ab164b79176d2269cf7903e996ccdd4724148a0ebc47531d04881ef562769420596891717778968107c9a63c86d491ac5dd885b672908e7820a419118633896d67a3274455f16acf436bc838a2cfcc5dd8503a982101488457d63043cf83bb273abdf0daafc5d966029fdc9235a9df74d024aebf08b4a9aee68f2b16185ceeb73a4394f015263771fda7979d947e84c616f380a87935ab90f0d9afcd79a6aad65efe6893ca21016915ef66b26aac818ba75a9985045d8ab749bd4a6ac8e2512febc2827e18965e37c9467982f0ab6a57cf70056981d4810f7e21158ada05fe354c5f3b1926802a7a3f88c411c2d01d9e56c2263bc64cf3805f0767b5f199b3d6535d3002b244ee2b0974acaebe9aa155ea9ee9b021d473f8cc545e45e227e8ebd5b4542b527ea5b4262a04f8169ba78586a830cc649d2b78e6f726da1b8e56db1f5e01a48bc3a379967a9772796450fe5f3863da94cef9671f4f56a3461239c3579ce7d2d6194cb84504a7a9cfe00f96e29d1ab69313bf95c021801f0507c1801081484682a15b241f8e7f345517ded639390958b448869ebb50087482f26fb8c7d7aca0f6720ae0d59f21e22e1ea66af51800fe717f444d9ea224216460a2e92f09aa3298879d388d8f2540dcfe5e617190e26fa6e87b9c91685a1131a5a14323bcde0be36d78510872b79a17745733311236875c827ca094f0ac6e5917d9bd6d0e3cd2194cf79e39be41b8dacf804447a44c6862571f0f496d9c8a8e549619b2b2f8af4d116a195cc1a34571a41a62fa09adec4744cdbe505f289047302a820a1a03ea9a2b6e9793d8a9b90b962b96e205d684161918194e1c085db26d812908ec429c199527d2b7d03e6b40fdf551cb70aa0a7a224b3c01bbe95762ce941d0ac72a1c0394acc994b1424985bbd6d64ec119cc535a00c229f37f7c21e32e92b9d71eeb88a118015b454ae4a0bc23bc8daf5b589628dd23dbca40966e0a7cc1463758abbd7ebb260da1dbe944df451fb5cd5f1437467d408509b5d5e726f265d93801155f282f73998f653e643c4493d70125f2c006b402eae4629efa69aac7ba8e8dc04b67009da88f6d8dbf148874cf4733845895ae13fa21746aa899b138b30b034d5e733380f66301dd129e030d43197c1b7f373d126
InA = c664383843e8befe514ab2bda15c5aad395931045b4b1c235b7bca75ad04216935f18f64dbf1d22c2e410c50e84468859fa80efbd78b1ab2cfcba7f235b471e5107e3337aa4de117333b3de593075f083a31f22e59964846dd454df9d992372561218a20d1f59a6628c65bf060d7a6956e0bc2e679c6b85b44ee1b07a13faedcde44724d4c98ef58516be8346ea4422008e96d68225fc9e0eebd5d8e149956cd1660c5eaab33387c6c17774073e9516009a007de75172991609901deb2808a3b93a15cae615e19852ab9a8fc415ce6f2ed203fc1f785ef6e77739d44eab1720ada4a7ad43cd96b99ad29b15c80b42f0566315841035e246e6b2358372c5257a4b97c3bf6dce693cf5c3f8acf468ac9ee2903a075eb829d9506e0b21504699f7cd7dbd72cbe0a36cc7e6b47f28a00e5e2a848bd95bbcaa9e14f9a72cc9edd253a61419e24dda294fe0de54df1fb14227b73d7cefad3bcbbcd41e74199797eab8089e7e56990f86eed4a3c8c7f39df1a70aaee6fd429d39854286e52d1bd8a0c2a8403ea58b010f0a175d0a974365a2558446b3522186cc2e0ff1b604caf2b211eb080f507ded619594de87d7f2655a2ea918dc384394a362a5a985c6bb935c14100acca189e84494ba27373ab1e955b228122807d78f1cb4a44b64459c90921308a448a83e14556129464459e9204cb2a90e3295833701d0bb6e700d9b3ed30f9599a31d6e00d871bfdf7e3e5a4e2a4317b233e4cded198074395092d9c9c513fd295e71cf4e0e85e2989eb4a31c752b5791c66842db51e4e8e150b23ad4c5724bff7a4f9061e5ae5c91a69615aa36fe6eb044b374fd2b88d5a532c608c8aacb091d08cea8a67a9028e620d7b41047d7a88d07b39050aaa67703101a492be1cc1f16224a91c9ce75b5e48ac5389aec2c7fd44b3521656a38e849b52d7c1dbd9138f868f78cb405c830a00a60f0e6a814efd8599726fe913b7b4fb36b2a94eacb7d938a1212d5f2aca551a2166f32ae45c2933ed945476014151448f649eca8b1b2b07c181e9153f4d7c78eea1b4ee00c4316fd073a1c9da8bbc2876f256e3d2218a180b2efc04fdfe61d2c417093e483bb0535a6892d52515ddbdeab4544b8b45e945650873f24025a6a65c3fc2202a244c695acd60f555f8b5ba196336daafd899ea09f1a8df918277889118383c12e5a8dda938ba5d0214148a16daaf196b6f12a20d17a6d1b57882b4437d9f0099cc483e731fabd2151e4febef2d55bb881f271a343306345096e8c4658a583cf2682d41ea924504ad0069c1764a5fc2c959a14d93ecadc18635e476b7d639d2bb008fb1e05ab6e454a30143f859f43477e7cc6253df152e2fa42958d67446dc9843c42e294b6196eb17c928811c0f686902d52cc24652e43344a6da135f6b2df84b4a802f703965274f8d5566469d9a146a65978d1d453f581881a52680f3eb9a89677563082bbd312bf53a569dc5c6f1c13279de627120fe804f6305a897fe479b1a5729836db61c9bf9c3cc96b9eb52a4836ce0608be6be33f1d2355bd45be2449d10e4012e3a92e420531056ea532039f8ca2daad8d0051d5b201b262db64e0c60901ae91d22126ce3390692a61b6e13d9a4b6ec44019a08e9241ca5e0d261baa092161eb58fed33f94e91a2bc18b7d1dfddc122de3c8d93bd6619945987c8af349714109a65b3a0f9a946b8843b1677d867aa8c5b38a1324d4a5cffb8d98e94e4d837b16c0a823f04ea17d4f470f7c46cb49d01ba23e66f966f111a525e662a0b69818801b8c4c7398f21954168551580766d4882b0f6586f4ace742d2c07b96dba61dfc8763aac92289e84afb1ae4afa784204e82f2c2461bc073da91c3615ca970f195e37b9e5a11143e1317336b320d349b6402979cc6fa1984a843cbf1435a519ca957fcf45658ddaaa8fc130e1bd3ebe5c8b4164fe6a0b76d6e3f252d170889572babe5085a68fb42bfbf45a9419372a7e926fc604faab4ce138d34a1e6438c649ad282d4077ed990b911656c6192cad9a079764f995179eb3225fc67fa71b008aa1a4821a991133497e28cfe02ca4a87cb087c412a8998d22fb4e807bb51ebfab53a6c9a6602e9cc54f1a8f9c53ef95c5f0879256b1d6fe2aacfd488943a49135d49fc54fd326e5963ccc451583030dadf30086128bee2b74902c58d9c0b4a10bce90a3848b75d4751038dd3ae5827f95a83476e060f38779d151a8deb0517b6a526415447b48f66ce28615a5e3c10f971397375a7c0ac5264266f4b930c34faba354d29f795c9aca392413586218e567d9bdb95209c94322a1d96c9a628f9e97abaaf6332e4e61ed0d904b119086ed021401be72abd6c460d50dd2a7d29ab890528d31070b7d781f2a6912074bd1fde427f60faab61b263c2d52cf6a4092b66e9080617554aeda564da0f5c9586c987541ec2551a7ca0d512bee052be4fef66f750b7c9bda78350ca4812394545041af7d550d7142e579db6d954489301dc4cd9b405f685d69470c325c490b
InNoiseSP = bf801ef9346a2d2160cff456a246c4c10e277bca9ded456ed94a385883620cd8f78430cf918cf9706c333cad91fbe1c05d81a06ac855224d03a613c2f1512478dc66c53b8a049a12cbe518224bfed226643c21155a5f28d9d97d78e70b0cc0af0622b3e8889bd8093442237a74f4dc1877a56594fdf081326fc3ab5b6a8fd0441f9331b64ed648688641198f2c84d16886c45f8856b5b04a245aff2a2e45cc095d9e24ca9922a6a4a28b507793dc8b7b84ebe0626eaec7e2f0c6a5c547e7938925cd1d373ea9979a3d2236a8e13ebb91d481955697157c76a2644081f7e96e587224ddd09fad2c3349ea6a6406155aa5425a88ce6199c78ac65e6a7d1a093ef0b27003e69df3a7094149cf4aeeb6e836b55a170437506a63090deb09cb4090252caf5701350c62eef2a4283287c644227903ee9626262da3ba6a35be090868fe580081de6a470458004e663d00169d71fd4b8ec0d6c603a094ec4524941f36027494310d5a585d30845dc22b0993b8b0fbea878d5e007343e980341c70d0f2553f0e2358d64872a9b91af5109c080fa05304406571856be3ec83d0181b030b7be53d869c1065156a10c5a4fc9bd07b63400dbb0c8568b5d84139e597060ce99f8962f356123e398e819d2881309a28a94faaf8caa79666a9943eb912b1473988a91564d79bb704006e2269201b68f91c00b3816d427b524e8d882da57b4193a954aca5c88438b82e575513700883c57cc5ce78b7bcddfed635718e1cd5b02545c532802054886d486ffddec2930110042a27420a0cce66d1dffaa1f7e47c0f53d3f4c8fe469410ea2831d9131f0049fb88d5016a691273eb9c9784e8ce08b23155b7c2a230c5e5a33f6f31e3c291219b993d6822cd5b822c9f506cd6398708e68339c49fa61ecae19cce241190bd54b2092ea8476e9637447f812a8de17b6a0e94df0a97a9ca83206e08c9aa05076823aa5be46e24cb05bc6aa11eb09a633b295aaa47e862e642b98e917e4e7ab5734e3b8063632b933c362e52b3e64f0020338cdf36fe1a173094ea5ac75e2086082a5b315d8f559e30598430ac27e6ac51b854079a8bc06bb5582e2ce348f1041845376f23d8a7b55441aa8c898ca60ebf57c097acd405df4f34b08a7439a9518d31dc78bc1c53be8b20d53b686b94717cdd76dace26bb25424eae6d47e7ae558be4488fd0b348bf4e42c4756a129bb62db6d7b25949df425653bc59a691db2a8bdc4e291aca98316bce06b0df63a0a6ed93c69b7a1510486318ad3dea55f44a4595a268b87a2ed4cdb00543a4bb6614bf4a54450921d2a9c474a0263885554924f119d7030a899859473a441276de02b71dd1f07b407d90ad27280b3fad4203656b466f5832724903e7db4c3a794e43a4f4416f7a9bbec811aa0f798952a4bc484e65222ca76c1471d1a36261b7dca89e5ab26415d1952568826ace34067713c2d15d991c1a5639139319a11d5ff2b6eea8229d6134b23ca6acd2569ea467b58fb58694c247d901c76c76f0c11a4b131336fb8bed2440cdb7a18d145b74aca0441f2d3151d09692e02c3fe06ad9e3bca57f3407513207b4436b4ffc795e0da3e75d78e13b295efbe0776b61ce1e3b95d130f3720cbd024a829410528c8066450bf47fec2b4b8116e067800c7753741175994e957082b52ac2a0f1570955a85fc608906291013a20eb7449769e6b267dd5553e1344dd46a700b60b0316ac1a6dfa4dbb64c449e5fd5e3a093c2570da1d9e4163b9cbd249180046221cae2d365725d7e2a8330641a4d0b7fa2d696aeed0c95416b0a3a274958c43155f2110463da5da99abc19ba40338e59f530c220d2867b0f69d4e41d6c63324c88805bacf3b2ab38209045561b3a79098bd8ea1e6e16cae5fef9ff4202e01030f68c517f93cd6c8128b84b68d8f9b74d2594e649f59f727709db60d52b16100c0349d841958fc38019918de3896484befe67181cc6627eccb7ea18710463d240a555f7c6be493bd2592653a4e8cdc47c8302ea9cc908257cc874c28a550fac6618b92985258614f0eac9c9443929d58e6a165e5c8837fe43646933cb04c9efd0407c97a2baf9d71bd9c7a5b4504f22c728056216a54f19419d8e72555e378b8db136ee0502c07c4a15ea72b1862f7a40230cc9a69cb6a34e6fd727393e8a9a85d88540f16a6c3f36d9d2aa647c9c10c745feb0e638fca46cc650974b91585decb5cd983e222ce109852dba42bd5dcffc7fda94f80d9147598d864a7e26e920608069bdf963a377499e4869fb151d07a5c0c8f388f3aaf6447540b92f9606cc62fb0e5b457820b2ad2644e99ad937799a4dc584ddab30a2db62b0f9cde26a78a739e629d43c3cd4ede87418a2348a8c64413e800e9ba3c45fa2642b6bc824cda7b0ffc6053a7b878516286adc754d05cde3e6526973390e8346fdf4a74d64575726e1172c6a89210958819b5464a1f0b01a8adbc4243a4a3999cc9b750949e38d84870cd9c93f88b2d167ec185796a6e19d042da81fcc42d
InNoiseEP = e09827a03ea2aae6aa6f42fc006f2f530c4820199d449c5316776d8d511421d603bd6b3ed5476500e481226b0ad6176a77811e346bd57cbbc404b4107239ac64ee63b5e89c53b8193bd9af8075b20d2fd49da9af0c01e908575e14f7144ad4454852812da1e5503897690469baee995969095e858096afdfd54fa4ec2aa9a21ac9a7ee4c1d0207932ac7104f61886b94a8e1617757f487e040976959afd026768a8d4d734adb3d35422363268fe98756a6fff5c29d3e8d434845de66a9b2692bfb19ba7d49c50f078c789bbae5ebc3dea9920d5fef37462a3d194b8f07ff186870047b5bc9ca9f658494db39ed5bfa820836789203615f0a61412e079ec76b671f9a79738944bb466d982101b296cf6e158d46432003a69ad89fd4c23f727fbc40fc62a69041b66b124a9f2978d451120ad11d1a81996bf2c8363ea0670244fee51c5218e800ac8838588979ca380c94698ba210dee9226f1fd49663bc422f646b04bd12b0d82cd212ad281c819f61a1cf1ca44e1508c8b67d9e6f2275879bbd2060c6f611cf952939561091109e2cc781723be2dc7a2c064429f4d6234596149466e02839043a7068f0aba01ee4b4d49da084402826de309a5313567b78e6041ec0ffab92ae74af93a260bf824b6da2f560a36842d92979469e2c660b4298b86b264fb18165f36eb60f95a036e1c7ae93028b90f49ec00fccc3de4678c25558d14238a9dea4e4498af7ba82785756a5610f4c920f1a5235e4c00b635ac80567216d444683d214a597e59bc7e4827514a62fc30b18c97f325a04208d059c2f1283f3273cb2bda28f666cf009ecad95b3d76d6ab0acbc3a1fd8bc5a8bfd87829e21000ec3564379710e6d6c0bde5e7c89d977e6fc393323d1a2db32d68866c4e5545bb6463f9c47528de934ecd18995562e6a5f50649b5b1473225d87ab7e16bbb0c6e149611213269272c9f0f2a7681776da3c0e6a1285bd43d930ba9e9f77e7601a16185895fa9df01937c11ab210b222c288d994d2f23a681ec270f41110648e46b414ec9ea62fe3ba0969796e9122d34d8099c06991a444720ca3ef7fb034c452fb6fe520954d5d806705e84b706ba685f4e0d199af682220b3b5ca72d322b55371e4b17185b5b5abe913cf2521f90cc548acde5c39efbd428362bde206a44b46a9ac756f2e00954ec212098e8bfdcdcea08d393532220c4899a9631b815bfb94da8dce69ffb02ef4b4a61840c771dab530d479f6730e2a94cc52f12d9caddce3eb48eca0555628b6320ead812ddd4e28845d755169ba0548289780533fa6e8cc4396570af40e412f36930ea994e8b459c78be17a7caa4454dc5097fe6ee1e66587337240710e1d6058a4147de4a9e122e5ad84d7741a700472b6025d5911c28cb30989024b88a379193123fe25041edc933072c17da306d911c34ea31b485a85b62c9ccb948695c3795a35d50af9a926465212e76332104a04c468264ad679e6cb7924bd421eeb8c034987916696d5b345e69e24e59f9645a016039dc13f97be926f1b4ed25a5d4489ddce30f77df143846e6b66f2a2843b6f28d466a8026fa70db095095f1862c6a3042561a6671a16bbd6bd0e9651227d502ea5cf014a52fc6e22a0fe7af8b075d94cb5611aaeb97b6a51f42b782ff661d6646db15cdca511e2dfb0b76ba0acb77f209d42e1ace29b4eb1bd98b3d98b9c44c903261b480815ce0f4db8c7f0306adeeec79ebe4b331e3a116a91b8d6d26738c9d2b8864338b9837e536153fc482f958a208f4dd05c8ebe9d802434441a474acdb437a00d644e2509d6a00a23d4d259fb4ba220cc61506007285ec30ffb13465558ef8f1d24b62d317060ef05dc3e89efca5de506fd614dc4fe4593e5816ed4cf21e49a5892230b6b292673440c46f245066ec205b3e8528daa705939919d721537e330dbcdf5b2c347b6018c3a540258bbd781e134e10ece44e92d563faf542826b55f45d4b417254cba552b4e59d0a61ae12d8044e785268d6e9020c1095ce501e4370be80d2f92a274bbdd3d5459396a0c6815896cfc93bd3a55610882424c5632a722b6f4b26a2dde918ca20e385f4a27c2d97e75a6d752944a3598bba362f88b213e95cd08b412fd8c505956a8b1a37a0b99147534ffbe2a63a52d6234103af39081e72f1a113c8b4bdb36a0717600284b189237abe7b5145315329262fe596019be860182da0516575ae68a845d85a698ae584a5c846cf826c8a90fb20e74174592861c3a22a9c0873e3c6e4da84720fe0d537edc72cad841286fc21a43005c943fe6bec35484813bdc88455f7102869adb43195c9ee995d267a8ed58081d0a50f8746f6e0c3349427a1be61ab060c3d47a9a6d192036c10d0c538fe0268474f18550e41fad727a9b4b0016ed4f3ee04d02f4cd1d3f934c7b590566e7e849f37d329b7f5dd3abbd1a9dec5c90b415545ee1123693694438c46564a02082533c22c594191d04469b21c7316a9913893a861f2d4ff009fae3c2968ff8c82214d2ba4f
InNoiseEPP = 024000700000c00300ff7b00f8bf003001b0ff0a00feefff2b0004000100000000ffbf04c0ffebff16000300010000fbbffcefff5b00fcbf01400000000400038000c0fff6bffeefff1b000c00fdaf00000008000000ff2b00f8bffd2fff2b0000000200000c00f0bf00c0ff4b0000c004400020000400feaffe1b00fcbfff2f001c00f8bfffaf00c0fffabf0040ff0b00ffbfff6fff0b0003000140ff6b000c0000b000c0ff0600fe2f01f0ffeebfff6ffffbff0a000600ff3b00fcbfffaffe0b000000feafff2b000800fd6f00f0fff6bf0340003000140000c0fefbfff6bf007000100010000040ff4b00f0bffe2f013000f0bf03c00000000c00ffaf002000fcbfff2f00bcff0a00ffef004000fcbf0000004000f8bffeefffdbff0200ffaf00300000c00300002c002000004001a0fffebf000000000008000240ff2b00fcbf02c000d0ff0200fd2fff0b00f4bf028000100004000000000000ebbffeefff0b000800ffaf00b0ff0a00fdeffe2b00f4bf01c0ffcbfff6bf00b0feebff16000140ffbbff1200004000000000c0fe6fffbbff0a00003000ecff02c0048000600000c0050000b0fffabf02400100000c0000f0ff3b0004000340014000f4bf0080005000f4bf0180004000f4bf030000ccff1200007000f0fffebffb2f00b0ff0a00fcef00e0fffebf000000e0ff0a00018000b0ff02c00030ff0b0004000080ffebff0600fdefff0b0000c0fe2f010000f0bf0440001000f4bffc6f001000180001000010000000fc2f00000008000040ffebff0a00ff6fff4b00f8bf00800010000c00003000f0fffebf000001000004000030001000f0bffdefff1b00fcbffaafff2b00fcbf00b000a0fff6bf0040ffebff0600028000100000c0fdeffe1b00e8bf000000ecff02c007c00000000400fe2f00fcfffebf00b0001000f4bf00f0ff0b000b0005c000000017000740003000fcbf00f0ff0b00f0bf04c0ff1b000c00010002f0ff020003400000000400ffaf0010001400ff2f01d0ff0e0004400010000000fe2f01500000000200000000f8bfff2f001c00100002c0ff0b001b00008000e0ff0e00ff2f02f0ff02c00030001c0000c00400000000fcbf0480000000f8bfffef0020001000024000e0ff020003c0ff3b00fcbf0030004000080000b0ffebfff6bf010000000007000400002000fcbf04c00010000800030000b0ff06000480ff2b000c00fdaf00d0ff0600fdef003000040001c000f0ff0e00fd2f00b0fffebf078000300000000180ff2b0008000580ff0b001300ffaf00e0ff02c0000000e0ff0a00fd2f0010001800fcef004000f0bf00c0fe1b000c000180006000fcbf0200000c00fbbffe6f010000fcbf0200002000fcbfffefff2b0000c002000000000700feef002000fcbf010000200008000100003000000003c000000017000380ff0b000800faefff0b000b000140ff0b0013000380ff0b00fbbf078000200004000180003000000005c0ff0b00ffbf030000ccff0200024000d0ff02c000b0fffbff0a000040003000fcbfffafff0b0003000280ff1b00f8bfffefff4b00040004400000001f00ffaf00f0ff02c00100000000f7bf018000f0ff0e00ff2f00fcff06000200005c000000fd6fff5b00f8bffc2f00e0fff6bffcaffe4b0000c00030001c000c00fdaf001000fcbf0180fe0b000000ffaf001000f8bf0200000c000400feefffebff0600fbefff4b000400ff6f0020000000010000ecfffebf0080ff0b00f3bf01000000001400fd2f00e0ffeebffdefff1b00000001400030001000fe2f00100000c002800020000c0000f000700004000240004000f4bf01c000100000000030000c00070001c0ff0b00ffbf010000fcff0600ffefff5b000000ff6f00000007000100002000f8bffeefffdbff1a00034000100000c000c0001000fcbf0030000c00fcbffe6f00f0ff02c00030001c00fcbf0000010000170000c0ff0b00ffbf0180ff3b000000ff2f000000ffbf0000000c00f0bffcef00e0fff6bf0380ffdbfffabffe2f006c001400014000000000c00040ff0b000c0000c0ff0b0000c0018000000000c0fcef004000fcbf030000f0ff0a0001800040000000ffaf0030001000fe6f00400000c000c000400000c00180000000070000800000001300fe2f010000e8bf024001300008000240ff3b00f8bf0040000000fbbffb2f010000f8bf0030001000f8bfff6f002000f0bf03000010000000fdaf00000000c0feafff5b0000c005c0ff0b0003c001400060000800ffef00000008000100004c0000000000003c000800fdaf001000fcbfff6fff1b000c00010000100000c0030000bcff0e00030000d0ff0600003000fcff1a00003000100000c000800000000000fd2f00e0ff0200ff6f001000f8bf0400011000f0bf0030010000f0bf03c000f0ff02c00080ff1b000c00ff2f003c00fcbffe2f00e0ff0a00007000f0ff0e00feaf002000000000b00030000000ff2f00300000c0
InRand = ef9e8c91a774589ed24f16603ee706cf863ae430553ca47912e090bcc2dad2ad
OutPK = 0868b7095909139920f60b50f0b56c14e0287116363521de40ce41b87cef52e34f4d15f1a4a7c4fe1681d3ea5094cd440f3c4749e928b212d8285b6545c60cb7ab1bcb591a8ad10f97c5f2c58d5ea8b5cb51fc4dbe14b6d12021b73581c697bac19d68129d09d10d310f4b09d4627544a06690161e7cb15da077898fe207225d4830c8657150a76bc1e9168b1fe0e929b77a7a91de7129b965a92f2d80c15f0074b4eaa8283bb5a7eda3c8a74a1aa396e629c02a8d98fe9fdd05f4a623d74e8211013241ae5f55a633aa65b6ed68c1fd41482262a856e75c75c81b7a271b191d47894d5987f86b23426b1368ae9c789cd298a6acb7cd4749f2a1fa3fa448db83e819976e6a9d99db028538a2234884d905099de876c108945c25780586319e1060d5f3986e00951017433599bd26cca7db8ec030bc1a565a59c61fc8a8c5f7ae087bab08c2e1222eac08d81ee84111153553abc5ae389bc9226e47854857395ed7920e8e01622ddf9393580a20877de6385c8d730ca612fe9889eae42067f97182dd2cd059b3f26c9d6384ea97603e01df8f172a5e2017956a81aae0272acbaed1efda1472a621f86c4e4133628293bdd603b20d64f251b649ff12766550a64377dc90c40d7c062d636550da144730060d4b185a1a75057cf6f2b159739306a20b6a5e4714ebb86248037216eeb3d1ac0440667330a0690bf8eb84f0f5fc5f8c2fa71427a42a225ae873cf3142c19b0350677e7106e4e8f7b8da96eb533a2afb565a33161aa66725a12f44d62bf5e17545a330596a357b65e06c51dd7150dbe9d85503b29a10e367911dd139bb65b62221893255cb6ea73f7067e3965207313d91f7a582b8fd9c84fdcdadb4b9111ce100b604ed3d88b1a86ec23b9c197d07ec69e2dc30756c2d95ef3d2e508d2991739cb5dca7759a4b8605c46a83464d86310c5ef6a6a240086c82ee1a8b1da31dc455d81ab8456e0916e9bc2a2668c10795e7206f2fcfda97387944f3a7c0a0c9c174d5892e7876943753c56cf951c8b8d11d223ae1ba55e3816d04795a95d81d1e92d0b8761f1443a6f25c2444987ed832fe4278e0fb81de4e03106e0b806dcd93190d00b92c2ca924ed230a6b7d23ca1f8dd8590c49ef050486da624dd42b49214a3a60098f934894d54eee870f820ad11d78834813d6fa2b69928b85a83e625e8a20a166cd40d85d8866980987d7002919d5111b5904837013c5795e1b3520cfc82940dd3f00e6d4538323760376a85fe44bfd5022d15646aeda06ae162743ae5a083d6403a917d783ccf9295890940599bc2faac9a4d468f9a0c6db7973d09525639cf0c1ae048a3a869be9316248728f7fb1c630424ccd7668daac8be6977f04069c034fa3c96a40c424648a4da0b808bb499435c4b3215c98d18ecbe09e201b9d1f473882343407b56605da6a1ec1745b45f1829f49eb80be284e589ab8b3df8d26528d8095895497bfdd0eb01a2ea4c59fd7fb2fa426f08ce8c252fc4875c38f8744a4385fc96cb1d8fcaa8ad26e217a92903865f259b5cc3840a95ff889656d031793528b9a2a46d7c58654d13a29c8fd99e38e7e81c1a0e926f8695d806eb6ad3866efa02046f2b00bade0d913ab1a8916da87d03d8a0dbd17f7b9d7692c6c5aecca2f05ac90a62b15497147181e1b1018d222ed4347d03bbd6f39d4b0caacf938632499d7c759b7eb6882467c4ea23e67624652ac414f92ea63295590b34930bb2b36744b0f54f434b863ceea67c171fd539616fee3471059c3d39f96c2ca04c5111c1870628a296fe66222ce84a2e69950961ca42ea8731230091db6492aa244f27729dc11c188753581cc8b25577e908d450df494febabf66c3885a7a159198c1010d569d0a952d494b4c729209b52a7020b1b6e06a81d8c43e9b216cc6c4291a7ced1c77313c423321bc20192c632a5f84e8819abc37848638f58a132122420ab2885d8742bbe2ece1795b1e5cb9cfd627e89256231cf185504619759a3e9ed5047d5bdc1208aa617af35c84a1272f986b9afa2331825ae107fa394a9a243039162e44014ca8d3c65b660cd51a73b4b217e97569b87836ba41d3da04b09f6e45ffa211122f266d43e8a0a66e41e1dd0082458261891d538094640080f9c60612a251d46cba88b8438ccc4228b6622ff81de322a3a20fb3d7179629a023d69c3a96cd5174818e037ab55e71bb1616e4412e5579d0dc941429a50c0fc37be6712a53e6010b5c8a94cc961604d05a847e8083703be17c0d133850c1f62ee765bd3ba64a0097223240a0dc7555d3db7274f65bc6a54b23477903f8a89d4a6ee534fb5af5783c381bb0a72ad76f25849b021d8871348d7d4fc9b61c68bc50c94e08562e165d4572482938656417d371568c6a3dca7007c26a5ef190e957df8e93f56c6be4da00b7a2e675a8a0094855188ae3ddee2bfb821673b389b8b32cfd83d88c986ae7e6f5f5b23e2dd62fc743e2063e8d3051862a54ef89ed823fdd14fbe3fce7182c27d90f981035d15f
OutRec = 01c00020000c0002c00000000c0001800010000c0001800010000400010000000008000180000000080002800030000c0003000020000400024000200008000140002000000000c0001000040001c000000000000380001000040000800000000c0002800000000c00014000100000000380002000000003400020000000024000200008000200000000000001000030000c0000c00010000400018000000008000000000000040001c0002000040003000020000000000000100008000280001000040000800010000c000180000000040003400020000400024000200008000340000000000003c00030000800010000000004000200001000080003000000000c00008000000004000140003000080001400030000c000100001000000002000030000c0002000000000400014000300000000180003000040001c000300008000380003000080000c0001000000002c00030000c000040002000080001800000000c00028000000008000000000000000000400000000c000100000000000001400010000c0003c00000000400010000100000000240000000040000c00020000c0000c00000000c0000c0002000080003000010000800034000300008000040002000000000000010000c0001c000200000000380000000080003800030000c0003c000000008000380002000080002800010000800018000300000000080001000000002c000000000000200000000080002c0001000080000000000000c00020000100004000200002000040002800030000c0000000000000c0000c00000000c0001c0000000080002c000200000000300003000040002c0002000000000c00030000c0000400010000000000000100004000100000000080003800000000400010000300008000080002000080000800020000c0001800010000c0001000010000c0003000000000c0002c000200008000380002000080000c000300008000280002000040002400030000400030000100004000180003000000002800000000c000300001000000001800030000c0003c000300008000240003000000002800010000c0002800030000c00024000100004000080000000040002c0000000000002800030000c0001800030000000000000200008000040002000080003c00000000c0000c0001000080002c00020000c0001000000000800034000300008000200000000000000c000300004000080001000000001c00020000c000340002000040003c00030000800038000100000000140001000040003800030000c00010000300000000300000000080003000030000c0003000030000c0000c00010000c000200000000080003800010000c000180002000000001000030000000020000000000000180002000000002800000000800028000200004000180001000000000c0003000000002c0001000000000000020000000010000300000000140001000040002400000000c000300001000080003c000100004000140003000080000000030000400024000300008000040001000000001c00030000400024000100008000140003000040003800030000c000200002000040001c0002000080001000030000c000000003000040002400010000800018000100000000380002000080001000020000c00008000000000000380002000000001c0000000080003c0001000000003c0003000000000000010000400038000000000000280002000080001c0000000080003800000000c00030000100000000080003000000000c00030000400014000300004000200001000040000800000000c0001000000000400000000000004000100000000040000000020000c0000400030000c0003800030000c0002c0000000080001c000300000000240002000080001c0000000000000000030000c00028000200000000200003000040003800020000c0003800030000800038000300004000140000000040000c00010000c0002400010000000020000300004000080002000000003c0003000000002000010000c0003000000000000018000000004000240000000000001000010000c000080000000000000c00010000c00014000100004000200000000040000c0000000080003c000200000000200001000000001400000000400028000000008000340001000080000000010000c000040003000040001800000000c0001c00020000c0000400000000c0001c00030000c000140001000040002400020000c00000000000004000180001000000002800000000c000080002000040003000030000c000280000000080000800030000c0003c0001000080002c0002000080000c0002000040000800000000400008000000000000300000000080000400030000c0001400010000000014000200004000340002000040000c0002000000000c0003000000002000000000800008000300004000100001000080000c0002000000003000000000c00
Key = 3c763fff910725780ae666ae0d91de15edb5faca0b8c2e22c318014401f91cff
InNoiseS = 8159e4d8f3901f0cec2355ebc6511fa4993a1576af5257b606f5b5317703e6b78b4053961048db1d4661b68e7bd70c8a00f758c257fbb81ed7cc2aba5fb098a4a0e8d5b5466ad209a639d99c0408eaef04895cae0cc75a18838a2d4517b927807d1e83ef9dd6f1cc1d42ca623b720581b804bee5b95ea47f8a7440db5073166fc595b314a519c178bb37b14b7b18cbe4d68027c45acb6760ed815f035b7b108c4193e470611f2e413d50e7d0596537cfa86cb93c4400c8240978a9d2325f0d30776de50e351662f2d97c8878468dfa5555618c0e25e237fe268658069153d90ee7552296b0853f2e2787853e2a72accf3dda02b203bca258b231b8b60f5fc0aa02b5680b15d6122e8d8bf5a7c474fb867d4f9840a47a198ba81e0d20b55692c528f0d296aa6ddb0a0e868fe41c00c01ba21900740a9cb3469e0948774fd769215a2b8ce940f37ed2b3e989c1883c548a220b88020dad389e55175989f916e62edf3bfdb9569ba33f8242a19e1c58141966be01e50c9514179644bfe6e2b0352d6d17eb637a498a5fb0d57181eb5400260ca0737e59038053a543cec243ee1da72263a0bd3669d4198b62855aaa315a7254603326e4a209116ba66bf9e7abfd34619adbf4086528fb24ab9780e54690695646eacdbb7e2f111782e11001464c22e74e52ddcba7a653bc822f6aec2ac0b694c9809d21de4e404e086cb67e7164b5018d29c3f64da96c1e7291949028ee6d279fa4314b26dc4515f95cd8436dc61a1c0dd429fe3652c8048c09392999b93b96de1be819e833d40b9f20440132d94b2cd13789473b5b87b41c75a3a5da6d8880013d8246ead4983d33c21e1ca7a6ac45e60c0e536ccd348821ce5bf59829bbc8a6357b5839cbe6d9a47bae4bec2963a023766b7d835f21d25c0bcf43b064400969a5ec08a50d245954e8c433bfc06347df623aaf988b17680fe0709012dbe9f3a071f92919de80f6825284a35929619732367a166b065ec83f9fe53510c0b84714db410b391ea1851d1313af396d8112b1c608300123d8d1c47df0bae78f97ca03f988d3ef3697aa76a11ba72e013d316a83edce235e680d8da0e6009dd019f6652ee8111419ed60586a116a637c9d2fb8ddea48384945337cc9720b63f6f7af590e4410d7a6be0c4bdce16776e0385ae3536a81104920c449298a8a0269c2d731a1b561a4e302358445cd1647abb5e54f96b07982e60a5d6200b9070949e6f974771cb9e3080d4bec507e3b462e8fe72228656201828f98d31b736e6dd0de704501dd3e069e7a070ae89c2e66ffbaae926426ae8d507f469b348f0996fa70274a90aeeb22ae51f11365123d7aa93ba0f309ea161f66cad5ca3795563fdcd0717d8650cfcf49821f5a600444b067f7d9a9619f2da086d1877dea143a77097e6999612155e9544a4c88a682e5014a8086c18a6e88942bc38254ca4c3021641b434623a046138b9166039e46e52bc2654f52cc367917fcaa77c7ddf798e6930f6cff97d8305c5f1323047f826279a115abf31470bb6868a4cc9a1f099246758a9801b769ccf145809e4b0d77abd4997d1bc88d90cd1a26ae6383fbd7d2aa3026ef860f9624ad092839b7d5753f1e266ac02614e1dc23052bf8171268aa8ae6c67105a38a08cfd93d7a0a35f5071104f7820632c760756ec263784676aaf708d6699fe09534dc1865cd11b1a58c190a20d93e33204475daa45f7c11e61900754ba3e93827fe2a2212a0f9839c22924ae69102f1ca4c1e1b8125df684cbd1839541b856d75825dd24a1a615810541348020f56952d89435c006d4aeb365ee11ac9a14709c8a894642265d03022243bcef2826f94227d02a1e6851c98c124162681a5113eddd24b3d889b58c0fe2a396a67b8a952b627c20ce5c0d8d66985261ad13b7658ad0b36ce4e24435809b928dc229dadbefccced1746a616d8d202037160442edde9e0f730542355d9cbe81433ef1e8714276dafb05671149c9a77e69195856e9e315820ab07cf35492a0b8009bb7c913ccf34ab5589ad0d6d7b6840b9673945ba16667a03cfcd70a70d14718c5b228566b54fa15fd1100a7e7406d72c6494e14643030d35a44d93325a07083cad85ac1f51d05542402eed5bf08e4e1046c3b4607ff864e4681581376db62ba977815e28203e066702c911593ead01d6ac4c4a69505e56ce6d59ae149631dcf19c2b0d8f05846a9a33901cf078fa35aa5d3f67d52649769daa605282581dd8f4c0f6156b2208841bd3c1573b42fab7c74db0aa0f4f5927e24765d83a307b644700704bc0bca665e1a8c240a9e4296d0873a6041d18f9633738402682fc23752931c611b3e526f2d43d95a346da7835e0662a68daf4de5e2c7561b1b9e2a836144be8841e157f62e22aa0293cb07183e0b9e4b6bfcf6b7baa91353264ad91795e2458125d441a4fb04ec0245282a18abbb39f6bd6c695b392d7ea22499eb22c5a795223191848d46f5691615b274ef72bf28d4226928947cbdcb02a0bd8e28ed45a
InPK = 0868b7095909139920f60b50f0b56c14e0287116363521de40ce41b87cef52e34f4d15f1a4a7c4fe1681d3ea5094cd440f3c4749e928b212d8285b6545c60cb7ab1bcb591a8ad10f97c5f2c58d5ea8b5cb51fc4dbe14b6d12021b73581c697bac19d68129d09d10d310f4b09d4627544a06690161e7cb15da077898fe207225d4830c8657150a76bc1e9168b1fe0e929b77a7a91de7129b965a92f2d80c15f0074b4eaa8283bb5a7eda3c8a74a1aa396e629c02a8d98fe9fdd05f4a623d74e8211013241ae5f55a633aa65b6ed68c1fd41482262a856e75c75c81b7a271b191d47894d5987f86b23426b1368ae9c789cd298a6acb7cd4749f2a1fa3fa448db83e819976e6a9d99db028538a2234884d905099de876c108945c25780586319e1060d5f3986e00951017433599bd26cca7db8ec030bc1a565a59c61fc8a8c5f7ae087bab08c2e1222eac08d81ee84111153553abc5ae389bc9226e47854857395ed7920e8e01622ddf9393580a20877de6385c8d730ca612fe9889eae42067f97182dd2cd059b3f26c9d6384ea97603e01df8f172a5e2017956a81aae0272acbaed1efda1472a621f86c4e4133628293bdd603b20d64f251b649ff12766550a64377dc90c40d7c062d636550da144730060d4b185a1a75057cf6f2b159739306a20b6a5e4714ebb86248037216eeb3d1ac0440667330a0690bf8eb84f0f5fc5f8c2fa71427a42a225ae873cf3142c19b0350677e7106e4e8f7b8da96eb533a2afb565a33161aa66725a12f44d62bf5e17545a330596a357b65e06c51dd7150dbe9d85503b29a10e367911dd139bb65b62221893255cb6ea73f7067e3965207313d91f7a582b8fd9c84fdcdadb4b9111ce100b604ed3d88b1a86ec23b9c197d07ec69e2dc30756c2d95ef3d2e508d2991739cb5dca7759a4b8605c46a83464d86310c5ef6a6a240086c82ee1a8b1da31dc455d81ab8456e0916e9bc2a2668c10795e7206f2fcfda97387944f3a7c0a0c9c174d5892e7876943753c56cf951c8b8d11d223ae1ba55e3816d04795a95d81d1e92d0b8761f1443a6f25c2444987ed832fe4278e0fb81de4e03106e0b806dcd93190d00b92c2ca924ed230a6b7d23ca1f8dd8590c49ef050486da624dd42b49214a3a60098f934894d54eee870f820ad11d78834813d6fa2b69928b85a83e625e8a20a166cd40d85d8866980987d7002919d5111b5904837013c5795e1b3520cfc82940dd3f00e6d4538323760376a85fe44bfd5022d15646aeda06ae162743ae5a083d6403a917d783ccf9295890940599bc2faac9a4d468f9a0c6db7973d09525639cf0c1ae048a3a869be9316248728f7fb1c630424ccd7668daac8be6977f04069c034fa3c96a40c424648a4da0b808bb499435c4b3215c98d18ecbe09e201b9d1f473882343407b56605da6a1ec1745b45f1829f49eb80be284e589ab8b3df8d26528d8095895497bfdd0eb01a2ea4c59fd7fb2fa426f08ce8c252fc4875c38f8744a4385fc96cb1d8fcaa8ad26e217a92903865f259b5cc3840a95ff889656d031793528b9a2a46d7c58654d13a29c8fd99e38e7e81c1a0e926f8695d806eb6ad3866efa02046f2b00bade0d913ab1a8916da87d03d8a0dbd17f7b9d7692c6c5aecca2f05ac90a62b15497147181e1b1018d222ed4347d03bbd6f39d4b0caacf938632499d7c759b7eb6882467c4ea23e67624652ac414f92ea63295590b34930bb2b36744b0f54f434b863ceea67c171fd539616fee3471059c3d39f96c2ca04c5111c1870628a296fe66222ce84a2e69950961ca42ea8731230091db6492aa244f27729dc11c188753581cc8b25577e908d450df494febabf66c3885a7a159198c1010d569d0a952d494b4c729209b52a7020b1b6e06a81d8c43e9b216cc6c4291a7ced1c77313c423321bc20192c632a5f84e8819abc37848638f58a132122420ab2885d8742bbe2ece1795b1e5cb9cfd627e89256231cf185504619759a3e9ed5047d5bdc1208aa617af35c84a1272f986b9afa2331825ae107fa394a9a243039162e44014ca8d3c65b660cd51a73b4b217e97569b87836ba41d3da04b09f6e45ffa211122f266d43e8a0a66e41e1dd0082458261891d538094640080f9c60612a251d46cba88b8438ccc4228b6622ff81de322a3a20fb3d7179629a023d69c3a96cd5174818e037ab55e71bb1616e4412e5579d0dc941429a50c0fc37be6712a53e6010b5c8a94cc961604d05a847e8083703be17c0d133850c1f62ee765bd3ba64a0097223240a0dc7555d3db7274f65bc6a54b23477903f8a89d4a6ee534fb5af5783c381bb0a72ad76f25849b021d8871348d7d4fc9b61c68bc50c94e08562e165d4572482938656417d371568c6a3dca7007c26a5ef190e957df8e93f56c6be4da00b7a2e675a8a0094855188ae3ddee2bfb821673b389b8b32cfd83d88c986ae7e6f5f5b23e2dd62fc743e2063e8d3051862a54ef89ed823fdd14fbe3fce7182c27d90f981035d15f
InRec = 01c00020000c0002c00000000c0001800010000c0001800010000400010000000008000180000000080002800030000c0003000020000400024000200008000140002000000000c0001000040001c000000000000380001000040000800000000c0002800000000c00014000100000000380002000000003400020000000024000200008000200000000000001000030000c0000c00010000400018000000008000000000000040001c0002000040003000020000000000000100008000280001000040000800010000c000180000000040003400020000400024000200008000340000000000003c00030000800010000000004000200001000080003000000000c00008000000004000140003000080001400030000c000100001000000002000030000c0002000000000400014000300000000180003000040001c000300008000380003000080000c0001000000002c00030000c000040002000080001800000000c00028000000008000000000000000000400000000c000100000000000001400010000c0003c00000000400010000100000000240000000040000c00020000c0000c00000000c0000c0002000080003000010000800034000300008000040002000000000000010000c0001c000200000000380000000080003800030000c0003c000000008000380002000080002800010000800018000300000000080001000000002c000000000000200000000080002c0001000080000000000000c00020000100004000200002000040002800030000c0000000000000c0000c00000000c0001c0000000080002c000200000000300003000040002c0002000000000c00030000c0000400010000000000000100004000100000000080003800000000400010000300008000080002000080000800020000c0001800010000c0001000010000c0003000000000c0002c000200008000380002000080000c000300008000280002000040002400030000400030000100004000180003000000002800000000c000300001000000001800030000c0003c000300008000240003000000002800010000c0002800030000c00024000100004000080000000040002c0000000000002800030000c0001800030000000000000200008000040002000080003c00000000c0000c0001000080002c00020000c0001000000000800034000300008000200000000000000c000300004000080001000000001c00020000c000340002000040003c00030000800038000100000000140001000040003800030000c00010000300000000300000000080003000030000c0003000030000c0000c00010000c000200000000080003800010000c000180002000000001000030000000020000000000000180002000000002800000000800028000200004000180001000000000c0003000000002c0001000000000000020000000010000300000000140001000040002400000000c000300001000080003c000100004000140003000080000000030000400024000300008000040001000000001c00030000400024000100008000140003000040003800030000c000200002000040001c0002000080001000030000c000000003000040002400010000800018000100000000380002000080001000020000c00008000000000000380002000000001c0000000080003c0001000000003c0003000000000000010000400038000000000000280002000080001c0000000080003800000000c00030000100000000080003000000000c00030000400014000300004000200001000040000800000000c0001000000000400000000000004000100000000040000000020000c0000400030000c0003800030000c0002c0000000080001c000300000000240002000080001c0000000000000000030000c00028000200000000200003000040003800020000c0003800030000800038000300004000140000000040000c00010000c0002400010000000020000300004000080002000000003c0003000000002000010000c0003000000000000018000000004000240000000000001000010000c000080000000000000c00010000c00014000100004000200000000040000c0000000080003c000200000000200001000000001400000000400028000000008000340001000080000000010000c000040003000040001800000000c0001c00020000c0000400000000c0001c00030000c000140001000040002400020000c00000000000004000180001000000002800000000c000080002000040003000030000c000280000000080000800030000c0003c0001000080002c0002000080000c0002000040000800000000400008000000000000300000000080000400030000c0001400010000000014000200004000340002000040000c0002000000000c0003000000002000000000800008000300004000100001000080000c0002000000003000000000c00
Key = 3c763fff910725780ae666ae0d91de15edb5faca0b8c2e22c318014401f91cff
InRandA = 8f0774d3d5350bd8a9f1567b6408f044018892f845055d532885b240f813fb98007cb69e66716bc3e67f69d0331b21c613b367dc3263689b62a8b38b02846af41cfd8633f41b89aa2a7353c587b0d6b38a4ae8ad3ae2b279f340239296bea34b2d6a7048e1e38f98a6f3087ec2e24d9ff11a21e1f7b0a01e00e6b1a85c8e9c9fd986177153f76cc8b317ad0df744cf8498f01b7284038a91106217e511a0cf20ae7c5203e0ef196a552877585ad94c3b277e8b5edda7e2cef1455a066e09ef92365f19bc4c86044486498f6f4783667f72431283644708d03b534dda98dcae6692404fd49cad29b10115790de190f7eba815d93265deaf17f7d14651f8962e28394cae148d86181f7a81a941d1161198ab9d0fafa01525a043d6def1321ead41007fcafbd1243a1629d31e06776b1ba67a1bce2cd4cab1062b59877fda306afa8103adc95780c7f44b1b25ad03ff3d669d2ed2c42b46bb739ec5920d3e1f046469bb5c8d178c6caa73b82857ea5934fb87fa994c08a88291c2937129ade1e8f1a40899df5952ccbb2506b9e57796a26e999e2bdc966ec2aa89c4b8a85c15493a198472a857602f16cca5189ba0a303c6163a63d0ab94634512172c8d56a7917644937ab8a3a889f113a9738beea09f8fb2581e410689a626d38b2a3747d6873748b0a21040c8942e0e289f42dd812c298a23a5e7724f3d33cd619b82830e411d10fb9474dd95162587ab0d81a28d698e1a79e50b624f236b713a703bc46ff245387dab0a6bb77b0e0e885e7851aeac70e84b6d4a2e24bb6f9900d803d513b3ece9da5d495a18d09f61c3b50876967213f2cd4784044e5bdb3544fbacb01242e86ab0e4407bedd1ba31de696414b8a03ed07e227282602f9175a73e3698d696b54616b46b7caa419b870487f2e0869bb311398fd548897aba4a8a04f8d9b0152fb414c9a8333a48e1d7a19a7c864df42dde180148441b274beaeab25cd7cdaa5b3e369e0c16d1c8f20e2b8e5b1e70298e98651dd965a7a858a31f87c4da9a6c1dc20e025ad45f1f6b6372d99866b700d047d845b4b40563d039463bdd4e3e3150ec4aee0646b635aebf064ca1e9e7ee2483e46028a316989adf7483c160a08dafbec43aec6da81950a057fa20eb8046b9cccdb42c5e1938e7766c6f653948d1102cb399c5856fd91e1f667b27d205378f1aac0b83356cef589e5282300d8becfb547c7c297eef0c97335e1bc08869b78d46b6771f060b99b837dbee82b874a871cfe16937a4f07ed01815d7aec5664e13e755bd2c3df61f43f7c2b26e6610f5a9cc44a84c21015a06b0a72c22c68aa4493ea6d62f6258ad8e5ae1effa32c87f49431fd34c76995f85bccaa0e091231bafe3b614a0a881b1cb959427dbd3afcb9e4294c6e35d67902a908c1c42936aa258ca60953a9f4928f0820ac9f00d3c72c07bc11fc0954c0a72abbc3962a287da87ac994c1acd4aba4eda401c232c3a125814af2e2e031699bc0d600fa651f2484b1d7db75e22089492c574536e774a15c8fbb8d59164cda93b4066448da3fabbb7f52b8d6536cbea0474d6987f05c9e0296420c50a33ea26be27dc309b9201d5aa518586f58139136d7084585a3b2dc3c6b9895a0f5e468a4b00b0b52d98c147c641a2a334e45abc4289cc7f572324ba5be314e3e655b7a6ce63eb6ae217fb6f67cbb308350e91c48a88eaac9b24e8b35c05566d0e4cb2c1965b6a14593a1d245295aef119a57549fc4e86086badb512ac46d93ad0984fab1e8112a44a60a16e7051e00c630bf79042ad61a45147b1d7a531aa1c9c9bcd708ca12273daae848d990ecc46c228ad162e69302db52a008aea235a10af962b6b052c683b0d814fc74d4807076b8a0050789fa7569604a34d20b4e67aa5e6956e018b6e8696fe28f9649aa210a54d9c8c7c92b2be83a514a1a6f4e03bc721b180099cb14ccd66e812f97205a7310867f5348e6841309e8a7c2bc8fda8e336589d900813046aa96513a35086bd04745b4390ec2c7d981cf752df3578954751dab2265820ece73745903bb681cbe68f52a9f4cc7c30fab8380094df1296a1af88296b55b2a9b90dcf6a0aa8525f005706908b119727004570fb446a5a634ee44cd28e39cb53f707c9992baa7437f74d938e280a0bf29a40080da8d4798141d6a79c33d83e9b6fa01286d3920a1f5450b1c46241370533b1c5701e4f6a4ad720b208d7e567badc725c1e1364b597f03c4ddc1cc33d251d99a69ed744e04e5a2b8471c0a892fb67e0f75368b35f59c6aa6e9557f15b2cf78120a8575ffde653c968949254113406b4e5220833200c81c3013cea24983bffdeecb0f294041de340975c329b3dc9bda0a9562e436efc1b6c707c522a23c99e602bf103a01b5ea4029319f696a2919ab5c2c29a5caa59750c8ff424288e160cc02286f2ab68ac098ae8e59225c8b3579880486cab2da4e87d10348f5d97bdf20b791b60fb43d06bd88c3153c17819feef2c19df7d2cfbd4b74adcc61c370a16fa1521a2
InNoiseS = ad9613f7d3f429e39015b40b84b0b0913ec1c4208c24d4573b1e0e5cafc5c2e3304c02271d1271721028f125e6974c6682ea15cea2cbe61cd1c03c601a708e42401ffa6cdd6bdfc925b9e520914a5902162f2db0a42b389894122e95cb5b12393642bee7c43bcd394449a938e73625985fdd9897355e13a453e073ad38438fe88738627c7ca3d39137a8e996630b1644a01c0cc5ad8c7ba79da067693c0080bdbdfdae94a5622587c4635fe319f439c7805e194b785fb65e1ce58d446e131206b025d98e60d10a1afd716e79103863382943964362c19c48a3aed93dc2aedaa4945a3d47a07ab585c3b7e377edaaaf8e4552ec3cb049c66ce1a7d9157dd552a63008a3ea6ff2026505788d18bc0152181b7b52489864aa4306eece17e366a9a822ad131059258665298515f1b8b691e490c9190ae668b2e6aaae8633a9f4b1d1a1015009c041b50e55d0d3d19066108e58c3ba80a67213c851687b6494a5235c7810718aafd10b7295810284592327f2b37ab9cd89eb80b3a81130e3a604796d95b3eede92df111d7264d21483851394002743f9fe13555f35250499421f189a1b35a92a2d2eec18e03183042e9ee7eaa15b9c11f17b4009a33960f9d628a225ab1c2557f8dca1dec00f82f80437c10a09f04fc52d3b8f95c19d86603bd6be368d427f274d3946d0221240cf76f4c4bc86b963f1e72fdeaa7eda6a382b41ba210eec4bd0a48b509dae0455a4381e6ec80226920a7fc67649fe4017b26407624bfa60da5c47559f248793eb4dd1216665201762d3b64c4782cf1175ff2eab9c6868b764d27a8f29e882beee78db130563114a1c8d91f125748ea0cfe56361aaa55b8d45a507754d332b8e9c252728b103aa48c1d5243c8e9e9a9879564f61cc2bb8cb3cbec982167859524f78cb374bb95056505acd22f0cd2890162931d4a200ba1e8490bbae0b521ff93bbaad8ed3ae62d7246205f92f8a7180492c398f76674a1a77d4278ee4117c11f001b016dc057c4d8665e7b4608e7726c727356e550a6974a4a0fa77b6677a40ff5683712a24d066d00ec14b2f926ea6b0b01b16f21a28b1ac2bdd05f4c162cfc844fb3ee4a4125e84e0876a77ee05457931550cc6c96673cf9d4526959719170815bbacdc97bd629924ea99731238be3f1c27a6594182f1944af3235ca8ab8ca067a1c6628401b4cbd665457e01c5fb6fed88191b24aa65e08c4bad30e5f9a00857aaaa0092302090ce66cbe192089896a524074c4a4e007e8a466a741417d7fb4f6d85e5c656c9540075258e3e1a0b1483ab482ffab6be449be33d0369c637cc526ee663395e092051e278e6aafc2e70f707017e85ab8dfb292a0d20eab39a773a429cce65a7f236612f633d79032c88b58af02651a1a05166032a446457fc2c8a548a60af745b8d762a1118feed7308af00023ea521d4a78a1e4d44cd266aac096985cea3f490989413b3e9cc047cd2c1e7599a5e3e1f081c647185bd819a9d7764a991e0a04db7a375102c5201527c9d23b242ac5ba5022ce8afcc78fd3a722bdc69119158898e405e68724889d6ee56831c1a2f39e507949a998e9fc3f2640c861841ac7e5ab261b563922109416ea2c4e071b4a1e46bc6c87e03b4e58bce9d7cf40a78407e1f44076f8166dc809a933e219e084126c1acf8a8e14e570383a454d0043c46b5e940540ff1f9de329321dcf7b179ca7adbc33693dab233d5d809332a5047839e50b1f20540d3d4a1908dfc64869937ab9b1a4bb21334826b449db24bc0a85a26183e870c39ce0e38372ca844aad89cec673713461468958b7e24fe3873670eea199eac685e9e64732e6070efe23ab892ce3e8b2053f0c1edbe5a46b1d6d839818047b0f2ae2150b909a3e6cc818c9819e3a156980fc2aebb172ac57a8ced24854550532249d827e798a83916bb4271aa841c5e76b49be014651b59f151092193cce682e1ad237818746724819862494633a96217581bba6a8e1652829ff0c128111d5d5d6b5bdc707ccf09e479e561aede184ac631cc7f19de60babf183cd6e6e3d3a80cbb398c58a147767da3d5e500c956083ced0699a850aada1f7b558c86778d9bc21b02ed4f6beee8a6267244a0e87687713161195d94f6dbf55adb0eb95967880a94c358579d945c521f19f361d68818a8cdf01f0a0f4a125e96f3a984d68c8a8a43cc8bd9c64a1231de791e2754928c088a519921888d460d7c5548e7c9f88e360c8da46e7616865897aa4ef14eaceb7753103103c343358398a4530d8fc86a851999f4e49b30e365044eea61a4e47524198d0f9600d8b10155ee33da006469ab55782c46416195f2a153c264ff1d7dbbb72ca01c26d11aeaa642fedadaf88a7478acca65515ab881719c8200d8559e3a63b96155016b625cb61a09209ab89cb08b444da5e6990f466e286047a72b1073c67d9e5cef88ea2e2c3713f6b1c1bababb9a1f2698e814c6ef0f4bd8aa72a7daeb41364c77831f06720b34574dc550b6b44a3550613c51db1823
InNoiseE = 9869ddb12180ad1e6aa807a9709803867f57b8a8b7c9d6b2e6d3218f739e565a4064af20a14ea9914a36065df3804c15440d150c66588d6f3ed35828220d005ad2d8e630645a79142b3209fcb6431ffaa1ae85b26d4567abb2b44a096fae483f10173203f31ac4ce5faf521674f1065690a40af86e351e15c2f1f3640c3755cc8bf520548b0ad6b345ea8e0103a46b44c6ae053a82f998ff7c05bd09221793f90ed50d2f7328146755ab9e5943ad8b8f5d59723bb9911cd0734b5bb472bd84b43941cc04715aad31caf56c6e984c13783406fde0d5e00f7c4f1613f882a8bc4c4a145997798994920d20a350fc121051811888e25cca1a1439126008c967985956f59a7f039e68a0363b60113a559de89bfb1e68962a3887de89489b7b6d528b057e707a3da71a5aac31c372afecc9ee8bfc927648147d204b2c824fa36861029e41c9646ee30fe93a1357063045f997d09fa28bec090783def063cead9366d44ed6861537c2da5e28cf0a34024e4201738cb751c8595708a918f0aa79d6276e98c1608e89cf4e9b9a829b49c2341cd0cc81686bc551cb17133ae5185baf1abc2b37fc7cd4ab8cf04d562e29a18355521e1f126c75b625123f180791b65d94bc5f4696e5c06d1e7a49be544dd95e16c978c1ccd63f8aad341ba5b940bde106f49efea1a3e9ee481d0a163bc8b844eeb55eb7ceaf3162686aaa68d1c76b5a461adcb26af2ec714302bde25f203a20068dc3efc8158bab930559e56d4b0ed4d2a5fa6d1d677e262b9164ba9859a97e157ddc190a504f123d56907218a641840b6f55c1fa998693c1412671520a22c02690f9790d2d6c6b67f5e984da48b6e1e91e7affe38a765bd079b4d67a10da7a08ada86166a9aea80e43687a96003de5da1d1bb0018b9712f7b8a2c4af88617f449b4e3ae01f9006ded20f1142afe80f5d4c184d5989c6e24efe182c3258717e0204cd2893e043ffd1d34b59a2445fe56334e7fcb7709de3a41180be7026ab7a08b10179841aba0d34abc35ba1c0edd03e4e857c3a33956d77536718f5124c74814d0bb625a45e52b72336118a0fa382b608a6afcf8c12a8f0ea51a49ba947abbe7b0bef4a729d85364341dc20b46c7a4463cf3a22a928316f5137becc5f33ca2adae99664da189817093d3f58e55f18ddea199ece4fe21c0d8fba94ed76773d2ce5816c60b2e6b5815be238f54d838aecb992ece036de9dc5e74d892fad970a04cf5452fcd9a0c879a8254da8eac188e52dd48e2f983aec7284223139a30a7673d43cb9df86632f1b49bb2d462c20170d0957d52ae1d1a9f1261293492cfca0b671251e1f7977c72c8304090c70a61d7b01e493caa8e112ee4132a26cfa64c8aafe82061916640a69024c8d0da42b5627f8219dc74c537545e9747a9dac3ba160067aec5e45338a2a3e2e8b70d34d9fc596b3183dca4f0ca786d1483e9e17c59ff7f6d42ce8a94c45178d120ba8f5aa458e875b4434f0755985931d5835084478a8a8ed0184b14c5416ee76edb8a6b1822972092118f8c4c371c7ae318023dc536246315ce18d5abf3eb09eed7187bef9396683baf8238a22d1173dc7f2dc7fcd8cab87749c0dbcd1996415ce4fb055b9422c7c75d91aec088865935d235b2b679965839c24d85930499d274175e7954ccb6a69056714088798a2fbe6968ac3676433f50daef6d3ad46f3395d5d89ae455f0d36445b9577f40a9f26417812fdb80d10e1868b4d82225eaefb00081e3bd7d93019af46741b48c6ea1fa056fea89f43339580bc231db095a690e6c3823822d902df97603bcbec34da2e26b2426141ce1db0b9b8b4144a9244151d154683e9f222750e8049537c5262806ba0c41ac836bc13ed6b9c5350da5645994683a81a2fa4a18058d8a60a088cc8134b2809350650945d6478ad641a74db4e7f35ee0b0babd4247dd2b54a24d14a192cadcb898aa9d15672f9815609d2edb5f569b6295e6f17c0dd78bfe54538b7914a5f97ea71da80629311093499c4598d086d4c3471ae0f7d25bbd124653aea4c9be210a025db8d3753691502b0ea01e438b6aa041fc58a0c3c9d5c9819724e61b90cc74804be187555a59ae633e297ff507e96f96ca4c0421cc6b27454ad22859729dc7f4dc47fd132aa75b0d614a0defa674952c0308ad6b3479807f5afbc39ed451ee2b611441d4565a2b25cadd64e950552464775891e57db8842f9cc4a83b8bd526363bbb040fc61291886dbe8892fa71b20c6a29a1b159d8e695836ac8c97eed70448210e253b5a30651929108c1670f4afa10eb8d6252692566ea48a6e01b298c322d824cc59591d4813328da15447e90af6706a5ac42aead65931041c88b984697f11810d0365d0a6e42b2a617a0485b68da600811abe1d806fd975d13e5fe53a28f51250ba0606e3ab3dbdf49894c9c0310957d2819b08864a566866503a8db04f597be9cd721256c74ab736f0868548ad967eee6b0c4c19e03f66bf02d561071b399c54ec5e454664a5d12b2032121aab
OutPK = a92b2c41ce706bed456c92ba9c5532a9e3d4105a9c5053f9db372c429e2a4f37f86976be5123d98b2803e72f8e68e0cc468ceb4ed04c500a900a8017417ea51ac97cf2bc1d4b11dad2836c7c0f2f12f0c2b3ee6b78e12a313c406f90420b32ffb4ac56cf9c4b83ec5848a3d289dc783983a0165585d20141cf3ab2ca4193c4c903c033ce7feac95ad34ec9815a4b0662087c97b78305e551ea630195d74b2bcd824908b843de40415c9d580445f009c98b6cb56f091343a7a18b2fccafb362730bf1f139a94012c7216c825899655b4002654e53444be1426d5f85e4410ee16861cc9787a34d3667c19af379aa657683af1691d22dd42e2bfb377e88992c68f1ed90bcbae6a0fbb8c13b9ce2e9830d414b67537ed737b6af1844a7d93d71000402935082f00d168dbd9966be19e128d01b61fe3e86c5d05b7b09a3de0afd7017942df88da1d551213eb36ec1fb97447789691d904786321300049bac6867d6db9dca622aaf1722f706b822a0470b1769efe5bb7ca755b1c29678bf5492d7556029ff5814e8bb10b56ace0fb075c47f1a600a40b8b1bb4d6c822048e50faa67fa152df251039e2f72da3180546ed88420889d63a58e498a18a79f9ae325f4da9f4a195c61e67c671c54b4121eaa3e75428c32c19980e329b978e32981c9a36413612cb50e0c95b31ba10826108db55c1d975f4269d41eb534e80af196630146192150a3af2d627ed05310a4b110bbc230c26735bb14e7328423ce25158813fbe84d82510a5ab536182e1b4d46d361613920e96397b5425a7de3342b80b0b34ece5aa63f79370d29f54203559ecacf3aa27f40a33a1b26462bfc3e621b7e903b3e04b1648fd6ae5881061e02c0ab610930e7b2a89ef22e3042b6168a647d17c49ef4eada957c136886fe4d1319611a7131eaadbfe6b420b999128f8998464e5627a0a288c3f3e5457ceedf656904984c2f043104b9822ee939884fa043da0e4aa8d81596151143993208a47318cae39eba6bffe5a5940536052e497695258820a2dd836a680d4ad550e49bea5c229a2736080a0ca2ad69bc94e66c016c51b1b906bea269c8b9523c94154992d6698894a06143dbb5adfc9c881010b7490178a3854e09aec566d35a71d4f920740149fc36564a028dc4d2985f2648a2990b699f0505ebd0a13a7c696960e542842db439cbe1ca2409dc605def6d7064f563f8e51f4270911ff8806273d9b2ac3549b0c638f99e60c5c9d8a20d294796bb147e6695af4be69331597ad656c0f4474e7a73cac1808e3c0552148474eb250e4cd87a463716173366ede98e0e6ff7514cd6cad20ad72b7cf9507d16f828d505da4103f3c8a94555e8bf18df0a3423ea1cd945f29373144b062f489877d84c0d9f0335bb1c8bdfc5f008c4366d8a2cc1a860715c4113fe48ca9e368d952a4496ada4096cf7b621793bfc2ea4a728b256ad0f2386cb5a0598250c510b8551ae5fe4cb9ed868a7eb3d4bd4cd686e64072a5852743816bd12eba1b7bca8fdd90b0633f302fc534cba923b469e854179a852835cf771cd3d23a5a0d5b4904e46ccbc1b39f6728da4f702a21638d46d566532395366211c3a88bc226acb54e1b8a936fd67cd94e6e620f5ec0e2abd2803a25f72106b7d84dfec6077a012371f0d66a2ec6e92e08f8407b41c95e3a7736887ee32e3ca43e4c9ee1f1c59b433768c01e58f22242ed5455ac8fb6522d262c9d26817f10a59b3cf32d2e57a539181d41778e41cd445a811876249448059536965b39c953dc737d632fe18a1cb2d2641e3dd0b67c6e40ec002f005dcfc0634698a818cb2bcfca6f2058b0a1c37e5083231fa9d3ce886306bfd9e2fe01a919c69ad0fa134b399ca86b4a93772d30e305d426819d7f984e10b05aa3fa49612c65e89f0310d4d60c5f67b8672ffea26c76f8a31639bf56360396e11c17cd192a01d7e579ef0b9b2797780efe1487e7bb66bd1f60bce073b212bb1429a246761366900eab92662ddc2fd99786a45a688db084118deca7586663dc50c45d8f6e88560a01cb5e55c289d5e3095d71a75b74975a3757d680092e29abcbc3d19454ff07bd5b92221b087c4154f21c39280acb0a5268345b541fda116ad9f87ecee717089802aa2ae6f0ae4371a08ae7bc2cf30309ece8659ee2c59fea41411c34c19340d05a89711d2776648a695e8e63ae20bb7e3eb4bf2047a3d8528f9baa9050b818ca2fdca1b5c035a87f7be3e34d5aec5d8363f0554fbe8aaad471c441a5346a5879bd968b6fbcd7cec07a133a00cbe5be0de2a213cb785a5f728ceeaa4b85d6fa8421c7539a0ec430a9982bc9554808162282543d2b6a5c9374c41b086eff61a5a05843a5cc884888b6475b0729193d5be8679f60ac14468381f5e41a7917d2628b0740f9934815b58195f6ff3c0bfd0013324b18a98796ada66d2457af69c51669fd9fa5e3d2180b0c915b4bedbd18de7fe04aac453d1e875ad83d325ed74a578857bd60758885193814092abf83088ea5ccc83753532
InPK = a92b2c41ce706bed456c92ba9c5532a9e3d4105a9c5053f9db372c429e2a4f37f86976be5123d98b2803e72f8e68e0cc468ceb4ed04c500a900a8017417ea51ac97cf2bc1d4b11dad2836c7c0f2f12f0c2b3ee6b78e12a313c406f90420b32ffb4ac56cf9c4b83ec5848a3d289dc783983a0165585d20141cf3ab2ca4193c4c903c033ce7feac95ad34ec9815a4b0662087c97b78305e551ea630195d74b2bcd824908b843de40415c9d580445f009c98b6cb56f091343a7a18b2fccafb362730bf1f139a94012c7216c825899655b4002654e53444be1426d5f85e4410ee16861cc9787a34d3667c19af379aa657683af1691d22dd42e2bfb377e88992c68f1ed90bcbae6a0fbb8c13b9ce2e9830d414b67537ed737b6af1844a7d93d71000402935082f00d168dbd9966be19e128d01b61fe3e86c5d05b7b09a3de0afd7017942df88da1d551213eb36ec1fb97447789691d904786321300049bac6867d6db9dca622aaf1722f706b822a0470b1769efe5bb7ca755b1c29678bf5492d7556029ff5814e8bb10b56ace0fb075c47f1a600a40b8b1bb4d6c822048e50faa67fa152df251039e2f72da3180546ed88420889d63a58e498a18a79f9ae325f4da9f4a195c61e67c671c54b4121eaa3e75428c32c19980e329b978e32981c9a36413612cb50e0c95b31ba10826108db55c1d975f4269d41eb534e80af196630146192150a3af2d627ed05310a4b110bbc230c26735bb14e7328423ce25158813fbe84d82510a5ab536182e1b4d46d361613920e96397b5425a7de3342b80b0b34ece5aa63f79370d29f54203559ecacf3aa27f40a33a1b26462bfc3e621b7e903b3e04b1648fd6ae5881061e02c0ab610930e7b2a89ef22e3042b6168a647d17c49ef4eada957c136886fe4d1319611a7131eaadbfe6b420b999128f8998464e5627a0a288c3f3e5457ceedf656904984c2f043104b9822ee939884fa043da0e4aa8d81596151143993208a47318cae39eba6bffe5a5940536052e497695258820a2dd836a680d4ad550e49bea5c229a2736080a0ca2ad69bc94e66c016c51b1b906bea269c8b9523c94154992d6698894a06143dbb5adfc9c881010b7490178a3854e09aec566d35a71d4f920740149fc36564a028dc4d2985f2648a2990b699f0505ebd0a13a7c696960e542842db439cbe1ca2409dc605def6d7064f563f8e51f4270911ff8806273d9b2ac3549b0c638f99e60c5c9d8a20d294796bb147e6695af4be69331597ad656c0f4474e7a73cac1808e3c0552148474eb250e4cd87a463716173366ede98e0e6ff7514cd6cad20ad72b7cf9507d16f828d505da4103f3c8a94555e8bf18df0a3423ea1cd945f29373144b062f489877d84c0d9f0335bb1c8bdfc5f008c4366d8a2cc1a860715c4113fe48ca9e368d952a4496ada4096cf7b621793bfc2ea4a728b256ad0f2386cb5a0598250c510b8551ae5fe4cb9ed868a7eb3d4bd4cd686e64072a5852743816bd12eba1b7bca8fdd90b0633f302fc534cba923b469e854179a852835cf771cd3d23a5a0d5b4904e46ccbc1b39f6728da4f702a21638d46d566532395366211c3a88bc226acb54e1b8a936fd67cd94e6e620f5ec0e2abd2803a25f72106b7d84dfec6077a012371f0d66a2ec6e92e08f8407b41c95e3a7736887ee32e3ca43e4c9ee1f1c59b433768c01e58f22242ed5455ac8fb6522d262c9d26817f10a59b3cf32d2e57a539181d41778e41cd445a811876249448059536965b39c953dc737d632fe18a1cb2d2641e3dd0b67c6e40ec002f005dcfc0634698a818cb2bcfca6f2058b0a1c37e5083231fa9d3ce886306bfd9e2fe01a919c69ad0fa134b399ca86b4a93772d30e305d426819d7f984e10b05aa3fa49612c65e89f0310d4d60c5f67b8672ffea26c76f8a31639bf56360396e11c17cd192a01d7e579ef0b9b2797780efe1487e7bb66bd1f60bce073b212bb1429a246761366900eab92662ddc2fd99786a45a688db084118deca7586663dc50c45d8f6e88560a01cb5e55c289d5e3095d71a75b74975a3757d680092e29abcbc3d19454ff07bd5b92221b087c4154f21c39280acb0a5268345b541fda116ad9f87ecee717089802aa2ae6f0ae4371a08ae7bc2cf30309ece8659ee2c59fea41411c34c19340d05a89711d2776648a695e8e63ae20bb7e3eb4bf2047a3d8528f9baa9050b818ca2fdca1b5c035a87f7be3e34d5aec5d8363f0554fbe8aaad471c441a5346a5879bd968b6fbcd7cec07a133a00cbe5be0de2a213cb785a5f728ceeaa4b85d6fa8421c7539a0ec430a9982bc9554808162282543d2b6a5c9374c41b086eff61a5a05843a5cc884888b6475b0729193d5be8679f60ac14468381f5e41a7917d2628b0740f9934815b58195f6ff3c0bfd0013324b18a98796ada66d2457af69c51669fd9fa5e3d2180b0c915b4bedbd18de7fe04aac453d1e875ad83d325ed74a578857bd60758885193814092abf83088ea5ccc83753532
InA = 8f0774d3d5350bd8a9f1567b6408f044018892f845055d532885b240f813fb98007cb69e66716bc3e67f69d0331b21c613b367dc3263689b62a8b38b02846af41cfd8633f41b89aa2a7353c587b0d6b38a4ae8ad3ae2b279f340239296bea34b2d6a7048e1e38f98a6f3087ec2e24d9ff11a21e1f7b0a01e00e6b1a85c8e9c9fd986177153f76cc8b317ad0df744cf8498f01b7284038a91106217e511a0cf20ae7c5203e0ef196a552877585ad94c3b277e8b5edda7e2cef1455a066e09ef92365f19bc4c86044486498f6f4783667f72431283644708d03b534dda98dcae6692404fd49cad29b10115790de190f7eba815d93265deaf17f7d14651f8962e28394cae148d86181f7a81a941d1161198ab9d0fafa01525a043d6def1321ead41007fcafbd1243a1629d31e06776b1ba67a1bce2cd4cab1062b59877fda306afa8103adc95780c7f44b1b25ad03ff3d669d2ed2c42b46bb739ec5920d3e1f046469bb5c8d178c6caa73b82857ea5934fb87fa994c08a88291c2937129ade1e8f1a40899df5952ccbb2506b9e57796a26e999e2bdc966ec2aa89c4b8a85c15493a198472a857602f16cca5189ba0a303c6163a63d0ab94634512172c8d56a7917644937ab8a3a889f113a9738beea09f8fb2581e410689a626d38b2a3747d6873748b0a21040c8942e0e289f42dd812c298a23a5e7724f3d33cd619b82830e411d10fb9474dd95162587ab0d81a28d698e1a79e50b624f236b713a703bc46ff245387dab0a6bb77b0e0e885e7851aeac70e84b6d4a2e24bb6f9900d803d513b3ece9da5d495a18d09f61c3b50876967213f2cd4784044e5bdb3544fbacb01242e86ab0e4407bedd1ba31de696414b8a03ed07e227282602f9175a73e3698d696b54616b46b7caa419b870487f2e0869bb311398fd548897aba4a8a04f8d9b0152fb414c9a8333a48e1d7a19a7c864df42dde180148441b274beaeab25cd7cdaa5b3e369e0c16d1c8f20e2b8e5b1e70298e98651dd965a7a858a31f87c4da9a6c1dc20e025ad45f1f6b6372d99866b700d047d845b4b40563d039463bdd4e3e3150ec4aee0646b635aebf064ca1e9e7ee2483e46028a316989adf7483c160a08dafbec43aec6da81950a057fa20eb8046b9cccdb42c5e1938e7766c6f653948d1102cb399c5856fd91e1f667b27d205378f1aac0b83356cef589e5282300d8becfb547c7c297eef0c97335e1bc08869b78d46b6771f060b99b837dbee82b874a871cfe16937a4f07ed01815d7aec5664e13e755bd2c3df61f43f7c2b26e6610f5a9cc44a84c21015a06b0a72c22c68aa4493ea6d62f6258ad8e5ae1effa32c87f49431fd34c76995f85bccaa0e091231bafe3b614a0a881b1cb959427dbd3afcb9e4294c6e35d67902a908c1c42936aa258ca60953a9f4928f0820ac9f00d3c72c07bc11fc0954c0a72abbc3962a287da87ac994c1acd4aba4eda401c232c3a125814af2e2e031699bc0d600fa651f2484b1d7db75e22089492c574536e774a15c8fbb8d59164cda93b4066448da3fabbb7f52b8d6536cbea0474d6987f05c9e0296420c50a33ea26be27dc309b9201d5aa518586f58139136d7084585a3b2dc3c6b9895a0f5e468a4b00b0b52d98c147c641a2a334e45abc4289cc7f572324ba5be314e3e655b7a6ce63eb6ae217fb6f67cbb308350e91c48a88eaac9b24e8b35c05566d0e4cb2c1965b6a14593a1d245295aef119a57549fc4e86086badb512ac46d93ad0984fab1e8112a44a60a16e7051e00c630bf79042ad61a45147b1d7a531aa1c9c9bcd708ca12273daae848d990ecc46c228ad162e69302db52a008aea235a10af962b6b052c683b0d814fc74d4807076b8a0050789fa7569604a34d20b4e67aa5e6956e018b6e8696fe28f9649aa210a54d9c8c7c92b2be83a514a1a6f4e03bc721b180099cb14ccd66e812f97205a7310867f5348e6841309e8a7c2bc8fda8e336589d900813046aa96513a35086bd04745b4390ec2c7d981cf752df3578954751dab2265820ece73745903bb681cbe68f52a9f4cc7c30fab8380094df1296a1af88296b55b2a9b90dcf6a0aa8525f005706908b119727004570fb446a5a634ee44cd28e39cb53f707c9992baa7437f74d938e280a0bf29a40080da8d4798141d6a79c33d83e9b6fa01286d3920a1f5450b1c46241370533b1c5701e4f6a4ad720b208d7e567badc725c1e1364b597f03c4ddc1cc33d251d99a69ed744e04e5a2b8471c0a892fb67e0f75368b35f59c6aa6e9557f15b2cf78120a8575ffde653c968949254113406b4e5220833200c81c3013cea24983bffdeecb0f294041de340975c329b3dc9bda0a9562e436efc1b6c707c522a23c99e602bf103a01b5ea4029319f696a2919ab5c2c29a5caa59750c8ff424288e160cc02286f2ab68ac098ae8e59225c8b3579880486cab2da4e87d10348f5d97bdf20b791b60fb43d06bd88c3153c17819feef2c19df7d2cfbd4b74adcc61c370a16fa1521a2
InNoiseSP = 564eafbabe3db55e87c419bd7551d0e63228ed9c3ae2a107b7c02614350eec332d19a20f061f879a646868168999eaa9124a058f1565f8710c9669248a15abbe8b7631eb697ceb9b28a4d4359de12975c82ce417e389bde1f08a7960539e066d0288f8989d420a72040e44774bd64a3f0d0ed777e265520c1f75931eee184991718af619b1b62935f43e149068133458595e87e0a273a171714a1b9e8672fa8245fe8b430aa068ac93ef4da0ee1d88b65b3823f7721fca56771082dd0be86f4e811b7c4a838af224aae56534cacc3446d94450002f48ad0e7c4c543810677a937962ab26a2280f14548f7aff393e1a42ae25b56c941a4e7cb600d14dffe440a1d2de6a9027ed965521abd5dc26e25d729dc598e3c14924a29a2335e9fb3533de04e738edbd67096e0198635d3ca644a828753551c622a56acbe272ba06f4b409d922b68782d681d0501cca4f11351674cd6f2a2b06b116c994a123acc65e92e8c96406d8255f538768cb4e74af43a6e8db3da540da3c865a8d2c14e86852c3c97c26af554a609e184b1fe391861c73e4eda477288c1ca94043058236a668989d28a37629f18ce3754c5100a2ce34048e989e950ca7ab50c18e648a45d0e17a9ab49bd087fc46a8b597d32567a5013c58f4d826589c81c5464b29011e508e8b3ab65658105a5c8931deb5dea38e0190b62b6325523a59f287786fc6560421af46098cd686285103499b050729079154fc3a3250a6e859a1b3da1e291d86fc21db496df445d601c3b44a3346a1413280857ca1ff37d75aac5ddb99030a0998de562b4b580905b691f6f481d004be0bd233d28d36f253d1f65b05ab0e631fb661cd5fcc080e76a65160c02ddab089b6400dad4b2a8dc8763c15b9da59c640aaa31f168c657892e2e4816c5c51e80efef47f020991836306c40666e456c441548923ea44097171a19e199f8d2274887c4b54e4808ec5059ed786668245045e2baa1323927b5e5f8749fc668459a4daca0d8e81245b1eea482161dd8f488a6c8d71b88c2d23c0583fee4b3be04cfa344ced844afb41551013c73434fa739d4f0a82249080ed522f51663509585b6174905d5f0042635bfdc912a2e8f5a6efe99d67ea4d965c245507a560b3f2669817d4ee17019aa3d8171bd6304998531b0d706c1537cc2c1e0800e2b3558a12c7d019997a551009d3b12ac9dfb4b61aa2453609d787fb1a7f499db013b44089bbca19885602ae5c5d534aa1013e776b3bd76e9091fdcdc68bf15c65aaa284090dcd7ae9a634c8638a4d64688e7b144c2570858c17039d3b2d82c21714349bed5f1a5701511e79cae191e195a7b09a32999d2cb4291c4eda7c1da06d0985dad801a779613458756ebeaaa695f143d1a50da35e6b69b48f466cb479eed6154ca6ab5a5288932a8f8f62ab46238b97e0a14af0232144a0fa09444ac98b9700ebc819e86fc8b0092cbe5f2b0f60d6a1288f431d606c698d65c465850375634e01b6ab7b369d122874528136bdf8825ce63a621f056c12f00904a108400281da06824b8c5c1468f4931a2988db371620c7ebec23790c997beff4c90fa128459c8da6ddc802b10529b6305c6c41ca245abc65266e44bc4952e2adc7caa35607b20a8f1d0ee26c607e48224f22e36d68af19054115fc23741a28257a5d1ca88450867d7e752aea190357697beb4bcbc3f736924659d680681dac4d08cb8478ba76bdceb99a4864ad8b488b87d238bfd02c529834be431642371199d479b0c5f83b4f8196cc109d3a7292315fdb896992b52287cb61b8d28cadf1a44e58d0d25d5b0f084a3052408b4adf15acf6aacd47021431d9450c1dde8b98820fdd2c78aac94d0e36ef16328c3470552fa558c02693fe1c3135c4457e252f412a18ba0aec007a772de963762ce3a01b04bcf52e85b9cf121931c945ea126910001909f5e5e6b5c61aa7f456c5338a5999a33f216b1dafe3f0b74a74936274d9318906b56d609b295d0a73a10b05642272d954bc3370bd5a85a63962b551039bcbb4866b8e77e1dbb7fa336937eb9e18f6d5c0a5a927aea4b0bc7e736425e79772a0b90292f7495e48986f0543f5b97bca41b405a3fa47c8de3f2791adad8bdb4958da55351e91e6c4703d8d4f843435a9ce2d3dcb47278cc8826e567a314f94ab0a836570e7697d822857aa584818c822b858955e8aa0a51ae64a56865dce4e65032e76e0c0f610836d7d1752169bd59eba0fd206850ead8cb71afb671ad4304991b0f3e0640432e6b1251bfa9f5a9f71672d21790093d902c39d33081405d2156e1fd78ca1b3765c67d0c0e4aad4ad6731e7b6c79ea0456e6e7c1b8709405a21f0c9b5f83c405bf3d1631e8c6093b7591e71244b9212d980c4084ba73a4451f43089c8de175f344fb6691a06f54a5d2cc0b4d43321b0728b8e98bc5d0470104f06ad4819e1492fc922c42575a99ae6588e89c1ef6825e4582f4b6e548b1532236e10345b63e4743c078ec1c5ce0aca1125cb42841968654d9277c521
InNoiseEP = 1a6aea83846d6c49937f55ec5c228e41f5b31ca182ebc7bc872b9a54c55b088a774624ffe5c5e8b635272509daa7d4a43d628154aa1d9c9c62e7b2d5762d1436ac97db5cbe8afc18bc34c77d0713e553420c5c9811cdfe131c66b9e0867b39ea85a45b420b533342a13d4b94d11aaa02c9596067e1b25ae6193224e5be04538787423996bc6b55c1232da1724ad9b8d6056070e64bf1fac64db54e0ba7532fcd62cd82260afba990b6a7b40b03949fc7ea51082b8143c9e1800893b24544419ca26b228c64690b3550a825e196d2b348fe6ed39c814a9bd67c51519b7905b28f69915d292ff8ae3aca98e85c466cac501e3b9be5478a6c29e3d7bcbb7626cce6e7b29296c727255d90389a9f8e86995142cf54104a60d1a7f46cddb342366e06ac308afbb9ab76a8ff2624725a9bac3f7808217547093a73f8e698834338330bbe06b3cc60621795573167e6eb0f7d38e85b34c73d96900c85b414598463051397b506c8afa6ac54126906265bedaf23654dbca883935b0ae2093b2a4579e01917ca8ddac676622a04a3a605ceadb8f8dad6c7c33e6c9ec5fa89f1ae7279056c4504a039cba1b1e1efc5506951be573131054a688fd80ab0186bdd53c98d2116d61a9eb85b6a03c34ca4265196762f0f82cb7504896aedfd4191b96ac2a8f372a14d820d644773c204799417f67b34f522a6228f562ab84262564e12c2f875d464d05757ba3058416d21bf06627e59b3e5339e45fb436ee8131e82314ef3e2ec7920dbca8ba0a8d249ea5ad75443792ea550f63068c551db89d007306155ea80b016e8342b23660e950671107fd2faa8fc91631eea713a79a017895a70161be146d2d0517091bc3c208a06eb4131b44eabfcb3cd2a1df482d2a81c896551815b11f38d420edbebf5335c25aadd4e552fed05135b2fb24c4655b76006d097dca7e545385a9f9096b64802b1ccb9ae515c7f7bc6385327d5fdd8a29595c1855387c60d1a920888656551b52e91a335ecfc5c3d4dda55270a0ead48aaf03092514f8ba4f6eae5a4c1d38287d235a9cb50cb24518a972eda50d29fb085b98c25f950741bdc6a3853792d27a5a389a1bdc65772832a43eddd12524db26136eaaf5c9aceb1a25993cd42e249e7644979c0afab6a08047766b365bc3e5af585d7241b125ca81aefd9c1ec9ead98b9f0634825590eb132fd10af74d386e227000006efc1b8951862d242205005f5513cca5e17acb614e282bde9ee4c0fd66c76a8cb0d68a9cb49276c9459696c1c230fc2b5d7dafa9789298981df45b1712675d46967f6f4c01fdec92702d3886ff58027fa6d32a99bdf1c86dbdc17945fac98e3c19beac43c959c3967295c0a7a0df1b2362be267623434749ba64abea437529876b7a27073fa1478a037d46b4c0f0b082bd4b1650099550d494d88658199bfe969acd45122731d9f2d4500372ae9183fa547ab22ba4cfdd70634d729a868d78642826e04551936c092c4194ad59ca070ca195c662dd7bef43141e09659dc7db71e1d15f07176b3a258efd331199ee0693645e4348785c55908df197aed0fa0a2d8b0aab351505afada2fc456fa7aa4c23ba6805e7439707ac0167bf61c017fc88866d334bc4259c014daddd423a6004291a9883d889187da474dad31552d1a82412fc2dac9246932b5cd4f2724db50aabbe5146388985156248e92ab9e9807d796d590b40ac3543035191c4597001fa8c1fa1d66a8be47126998b611bcf8298a9fa686c9e42b4407ff20002a97306ebf90f14bd294867425d5dae0c15cc1af3b86cc3057c4a2665634525a1b1753b2ebeda0f9d95052d02d05818d44f3fcf98508e9c40afa08ab4e453cb34991431219f6c2e8b5161acae5fa88497f414701b9f8f06ab8cb49db7a628c47af05215ef6b349cede61083ab3ec22184987547a085cc620cf086dc2dd3f2bf2484fd09af93ae304b06c274e839dbc5e23cb6fc23cdc4a021e9ba355006202e890e0d4d03b15e501969168a0e04fc87526bda835ac44f04875434fe8bf9b63c52fc15406d0a6fe466cc6fd640b5241bd91f8eba1c401745ff085393e09e4ae80b4e95d33f2ea5832bac91f135757b28e0267f283b71430216ca52c2793d776bfa89e5ad10cd808fb898bd90f6e21d36680e74b7a747653301a5f14a24b17abb120b28a9f5331c96c1e89bc1192e9786c336a2fe654be988080d4a1e5800053066bf260fa391a1def437243ce6be582bf022724152f41f5fa2eb53352a07aea4f8c4cb7a0d9f3d3215d6aa3b971ce846228d757f3933a30cae35f88c125a80bedea69b44940a59d1080c78285b1d73954a3b63403d4ad7649bcbbed067622eeaaac36937570fe15021cd893d7d6929adcc5f378bca09daf2b2de09d4a1f9f83d556f9122895628bc41d25bef96e7835ad21bbdae1bfc775821dc66e0494f6f86c5b6bd2317ec53533c238a4fcb81d33875530128192eb8fd63755d92b74d03da66ded0dd5c617050e2554fce83f3a492954ad2125837dba00
InNoiseEPP = 000000ecff0600fd6fffcbff02c00300ff5b00f8bf058000000000c00180000000f8bf04c000e0fff6bf018000400000c0fcefff4b00040005c0ff0b000300010001400004000180001000080004800020000000fe6f00400000000100005c00f8bf0300fffbff0200fe6f0020000000feaf003000f4bf0000006000f8bf00000030000000ff6fff0b00ffbffe2f00500014000070ff1b00080001000010000000fe2f001c00f0bffdefff0b000000fc2f00e0ff0e00010001f0ff0e000070003000f8bffbefff0b000f00fe6f003000140003c0fe2b00f0bf0080fe1b00100002c0ff1b001400010000fcff0200ff6fff4b00fcbf00b0000000f4bf02400010000800feaf00100000c000f000300000000040000000f7bf014000f0fffebf0600010000f8bf007000e0ff02c0fdafff3b00f8bffe2f000000f8bf0100000c00f4bf05400170ff0a00010000f0ff0200003000000000c0ff2f003c00f4bf028001100000c00300001c000800064000f0ff0a0000f0ff2b00f8bfffef006000000001c0ff0b00f3bf034000f0fff6bf0000ff0b000f0002000000000b000200002c0000c000c0fe0b00000000b0000000fcbf0240ffebff0e0003c0ff3b0004000000000c000000fd6f003000fcbf03400020001000ffeffffbff0a00ff6f00f0ffeebf048000000000c003c0ff2b0000c00440004000fcbf0000002c0000000400002000040000300110000000ff6f000000ffbf0340001000fcbffb2f002c000000fe2f002c000400010000e0fff6bf03c0003000fcbf010000e0ffeebf030001000000000070ffebff0e0001000000000300007000e0ffeebf04c0ff1b000c0004400030000400ffefff0b000c00fd6f0000000c00038000200010000040ff0b00f0bffe6f00400010000100001c00f8bf0680ff0b000c0000400000000c00fe6f001000080003c0fe0b00ecbf01c0001000f8bffc2f00fcff02c000c0ffebff02c00240ff3b001000ff2f0020000400fb2f01d0ffeebf024000300000c001c0ff0b0003c00480fffbff020005c001400000c00600000c0003c0ffef0030000000fc6f00d0ff06000200000c0008000000001c00f8bf050000000003c0ff2f01e0fffabf0140ff1b0000c003c000000003c0f8afff3b000c0003c0002000000002c00030001000fe2f00500000c007c0001000040001c0ff1b000400ff2f000000f8bf0440fffbfffabf030001b0fffebffeef005000f0bf00f0ff1b00ecbf010000d0fff6bf000000ecff0a0000f0ff1b00f8bf0030000c00080005c000200000c0060001d0fffebf05c0ff0b000700fd2fff0b000b000440ff5b001800008000e0fffabf0280004000fcbf000000200000c00380fe2b0004000040fffbff0e00003001500004000340003000140002c0ff0b00ffbf01c0ff2b000400030000fcff020000c0fffbff02c0fd2f00ccff0200044000e0ff0a000180ff1b00000000400030001400fe2f01e0ff0e00fd2fff5b0004000180002000f4bf0380000000f4bf028000c0ff0a00008001f0ff0600fd2f002000000000c0ff0b0000c0003000fcff0600ff2f000c00080003400000000c000030fe0b001700ffafff0b0010000680003000040000b00000000300004001e0ff0a00fd6fff0b00ffbf00300020001800ffafff2b00f8bf0440011000080000b0003000f8bf00f000200008000300ff0b0003c001800010000c00004000400000c0f92f000c00fcbf0200000c00f8bf05c0ffcbff0a00fdef0010001000024000000003c0010000dcfffabf00c0ff0b0008000280004000f8bf068000e0ff0600fa2fff3b00fcbffe6f01f0ffeebf0070ff2b0000c00100001000fcbf014000f0fffebf0180ff5b000800018000f0fffabffc2f00200000c001c0001000fcbf0340ff3b00fcbfffaf00000003c0fe2f0050000400feafff1b00f8bf01800140000c00ffefff2b0000c000f0ffdbfffabf0280ff0b00140002c0fffbfff6bf05c0feebff0a000340ff1b0000c0ffefffbbff0200ff2f000c00fbbf008000100000c002c0ff0b0000c00200001000f8bffc2f000c000b00ff2f011000f0bf03c000300000c0fe6f00e0fffabf02400160000c00010000dcff12000240ff1b0000c0ffeffe9b00f0bff7ef00000000000500003000f8bf0040ff3b000400fc6f01e0ff020002c00000000000fdeffffbfff6bf02000100000b00024000100024000070001000fcbf003000400000c000b0000000f8bfff2f0000001000fe2f000000fbbff9efff0b0000c0ff2f00d0fff2bf007000f0ff12000040001000f8bf003000e0ff0600feefff4b00f0bf000001f0ff02c0ff6fffebff0e00fe2f000000080000b00000000000fe2f01c0ff0600038000f0ff0a00014000f0ff06000140ff0b0003c00200008000f4bf030000c0ff060002c0ff2b00f4bf0070ffbbfff6bf0100013000080002c000200004000300003c0000c0fe6f011000080000c000e0fffabfff2f003c00fcbf
InRand = 3bec20e879d06c7784727a350e65ef4a75df10bcda185de1bb4e4a6cf8d8e450
OutPK = e2637b35a9e43a2dd25333c125bb90407b7b1c0c62da269efb13008434d8a8f00d212f6198d693bff0062482ba182ce12bc16520d6928e1d6ea54a870adc94396e2f633e6a9b024f8878c64c8af86164fb6561717369db940d96a1844a7511105271785a8600fd062ec6e3f853a584ae238e7fc948ec1e3b2d1e24a679696eeb4a6a8e3d00f3d4428043b81ca050d3fbd03c036b400cfac70ab179eff09232c40f374991bb53d53f8c930e241105b31391fa9a65142d0c95b88b06c12c7c195296f91246e7687034eca81ad9ad1d47fb6c006e2245ebe8a179531c446976fe39028a06a1cb6451590f9c883095b9d543e36b26bd1506dff3f7eb9d79cad5fc62b106820f544e3688f09a386c07f0a7428892a80620f3da33bf19e595ac79af5d58cbb8b404862fd7b020e564a2551df746dc880b67098df5732eaf139adf20f41c8323c71e378f2e35544c12f446dd8536445a993f25a028cc3e106c9410dd5ed2f5f1acb1a02683e21c357153c056d2e755731f1aaab7dddd9a75cc159377ceb26404efd25e6676d946ec388a4268a1ee7317f209861adf78126f025363c9254839f465fa5e9e37098ebd8f633a16ee310a9d512fa922dd25dce24b364ba24388a72d40eaf13e4f535b61d8007690483f6aef6d4d07819744091a0e4d4a3ac85ae52f04d530a937aa0c81a858d7b38e7a4281ab20f186890d00bf89590650a5de283a37fcb2a4cf85c658f4148e24b478d8225f7e0ee0135c9e39568a6f8292261d856b9c3878741a11ac9d39aba68cb714292943e44aaf5d9d00385425d9407f99ba6a7743e9abd162c80895ea9585b611a205c90b9ad2188e6a903f5554c4a35996ce266a49371a4fecc68660be35055fe1f8797a5f6dce81e22414764c44d3ad981b2eaf415169855ebf5a4de3904227789c58d2a34a0c75e50668dfce4e4f2083a693a607370d5e9a79f943609f94663cf47c94e14d5708346b33ab51c2ba91729206356491cd57afd8ceaa0d3634d3257de0367110f05ab7253c2130989b9575887e0cdc6459f9e3b61d72416242e6c2b02a8ffdb98e5c5f6da8e7a13a7c7276ce47e4bfba1cdb000ce070a4bbed57413ac7e5110682fe86b0c5791644be6a7ce6169bca6bfab174b734918da1ce4a399a903be6e2621ca4a86f90e0bc4750819be2cc4603c4aef178c3865c9d858ce8a1f0519927fff327b906cc6e39a4238da0c7061fc4c8240388acd039ae8e7d68990fc78f5061362361c1e1869762ce6a066d24aa9ea4f8468112072fd16f8b314c5fb4c032725fb6729812fe9bdae138b81aba3abdee0ff740fd9a5ffa18205b3307e53607e90e7894767249ae95a436ab71798e1b5b48f4117cd56e3cf3a4912dae43bc63598a78f2ece536cbbd4320248df43cb845169a01981ffeaa2e9dfc17a8aea8675cecd86e7e9a544bddf12af07652cc4b2610a81871e66eb18e643fcd267f99b731ac72258ac4aa66a41a1cead40450876115119133449e2e5535b008957b7b6682e8271a9b0a4c0b4849fc1fc023ec529d2d6614d7e860587925b1eadb3311c90aa1597af55af1beb62dc01867dc0b932deac47adc91d7c1d93968041a1edeb5808a8883f65f7d11be85b8435d23482c081a9d6d3c5693a05aa66186620ed46a23118552673c96820a6f3bb3aa9e51c3a07b26d497c458ad219c5588f461311bc8bd702309f9b44aba430d81559989140f95982e871d502e02c3f161399a367910d526a2063b4892b507c0611d2d8d6d901e318e92eda13ac2c14ab3a9b13129552c00d529b975c1a8bfa0b55bc77488424af77b97d63fd78d9998158e51a297d286156a99fb6a5112ade63a1085228ba7de53c7c3f2d2131e510002ef92cf4c5a45570e07abc094ba294661e4cd96fcc3a7a1bfba84d1a2c8d0b2d550e20fd963d3100fa9d890540cacbc2babd97b6fc4052dc4d4abf77e6c5b8860219ed1276c9d5c566704a9d19e6f54d8ea63315079839a042ff0520797ce78b1489982c26aaa463b20a2e9ac710cb08473e79bd134416357e5216e3e644b71d7182a121dc0f1463e22aa44cc4f6246016cd1af2d119e82abbeae7b6b1ec05e38acee10fe422051c448a14a71a23a98594258d9525544fe697d752477c5e01922706d2ad10351262a32cf86859a180d7f2185bfe370663c9fe81b419ce52560d9552b95f013b31068eb447c528a48c53bff387575d61dda46a9499a0b0d59602591c31a7a20add950142d82719b08b460270b207e9a03ed91eee0e5d8203e5fa061f8e624195f05a4e4e9376e9dfba02d14325ec2beea8fc0b21e67e8b671d8a194e1f9367ada2c9a096c9a6d5c83ba9344d2d2026138ac89940a946090171fd868310fc29f2996b1046910a754243db02fbec676109fa25de969f3e626646209d38b9b3bf909c4d249e5ae2dbc119d779270aa3e332fa2124506a80f41c323a7e1a9486a0cf5002d1ae09f798670d981dfa07a313a254222a131163d596443ca8697e4990e0fd3c301e45874
OutRec = 00c00020000400038000100004000300000000080000c000000008000080002000000001800020000800008000000000000040002000040003c00010000c000280002000000000c000000008000200003000080003000010000000020000000004000240002000040002c00020000c00018000100008000340001000040002400030000000034000000000000200002000080000c000000004000000000000080002000000000400034000300004000240003000000001400000000800030000100000000080003000080003c0003000040000c0002000040001c0001000040003400020000c000140003000040001000010000c000000002000040003c0001000000002c000000004000300001000040000c0003000080000c0000000080001800020000000030000100008000340001000040003c00000000c0003c0002000040000c0000000080003c0000000080002800020000400008000000000000300002000000001c0002000040002c00010000400024000300000000380000000040000c00010000c0002c000000000000300003000000000400020000c000040000000040002000000000c0001800010000c000040002000080003400010000c0002800020000c000080002000000002c00010000400018000300004000280000000080003c0003000040002800010000800030000100004000140003000080001000020000c0003c00020000c00020000000004000280000000040000c0000000000002400020000c0001c00020000c0001c0000000080001400010000c00008000000004000280000000040000000020000c0000c0001000040000000020000c0001c00010000000004000300004000280001000040002c00030000800038000000000000280000000080000000030000c000380002000000003400000000c0000c0002000040003800020000c000080002000080000c0002000040001c00010000c0000c00010000400014000300004000000001000080000400000000c0000c000000008000180001000000002000010000c0001c00020000000018000100004000080003000080003c0001000040001c0003000080003c00010000c000140002000040002c00000000800030000300000000000000000040003c000100004000040001000040003c00020000400028000200004000300002000000002c000100004000100003000080001000010000000024000300004000040001000000000c000100000000300001000080001400020000c0002800030000c0002c000000008000180000000080002c00010000c000380003000080003800020000c000040002000000000400030000c000240001000000003800000000c000180001000040000c0002000000000000020000800024000000008000140002000000002400010000400024000100008000180003000080003800000000400014000000000000100000000000001c0002000040003c00030000c000140001000040001800010000c00000000000000000300002000000000400030000c000080002000080003c00020000c000300000000080003c000000000000300003000040000000030000000004000100008000380002000000000c0002000040003800010000c00000000200004000080001000080000800020000c000040001000080003000030000c0002c00020000c0000800010000c000280000000000002c000000000000000001000000002c00020000c000140003000040003c000200008000200000000040000400020000c0001c0002000000003000010000400018000100008000080003000000000c00010000c0002000030000c000000001000080002400010000800000000300000000180002000080002800030000400008000100000000280001000080003000000000c0003000030000c00030000200004000380000000000001800000000c00004000300004000040002000080003c00020000c000040003000000000800000000800014000300000000180001000040002000020000c0002c0000000080000800000000800010000000000000100000000000003c00020000c00030000200000000140003000040001800000000c0002c000200000000040002000040001800030000c000340001000000000800030000400008000300004000340001000080000000030000c0000000030000c0000000030000c0000c000100008000040002000080003c000200004000140001000040002c0001000000000c0000000000003c000200008000280000000080002c0002000040001c00020000c000000003000040002400020000c000240002000000003c000300000000300003000040000000020000400018000100000000380001000000002c000000008000300003000040002c000300000000340001000080001c0001000000003800000000c0001c0002000040000c000100000000040002000080003000030000c00
Key = 489c79a48135995c4c8cdeec1777a79cc68bfa7b167f21a25e92945b4004634f
InNoiseS = ad9613f7d3f429e39015b40b84b0b0913ec1c4208c24d4573b1e0e5cafc5c2e3304c02271d1271721028f125e6974c6682ea15cea2cbe61cd1c03c601a708e42401ffa6cdd6bdfc925b9e520914a5902162f2db0a42b389894122e95cb5b12393642bee7c43bcd394449a938e73625985fdd9897355e13a453e073ad38438fe88738627c7ca3d39137a8e996630b1644a01c0cc5ad8c7ba79da067693c0080bdbdfdae94a5622587c4635fe319f439c7805e194b785fb65e1ce58d446e131206b025d98e60d10a1afd716e79103863382943964362c19c48a3aed93dc2aedaa4945a3d47a07ab585c3b7e377edaaaf8e4552ec3cb049c66ce1a7d9157dd552a63008a3ea6ff2026505788d18bc0152181b7b52489864aa4306eece17e366a9a822ad131059258665298515f1b8b691e490c9190ae668b2e6aaae8633a9f4b1d1a1015009c041b50e55d0d3d19066108e58c3ba80a67213c851687b6494a5235c7810718aafd10b7295810284592327f2b37ab9cd89eb80b3a81130e3a604796d95b3eede92df111d7264d21483851394002743f9fe13555f35250499421f189a1b35a92a2d2eec18e03183042e9ee7eaa15b9c11f17b4009a33960f9d628a225ab1c2557f8dca1dec00f82f80437c10a09f04fc52d3b8f95c19d86603bd6be368d427f274d3946d0221240cf76f4c4bc86b963f1e72fdeaa7eda6a382b41ba210eec4bd0a48b509dae0455a4381e6ec80226920a7fc67649fe4017b26407624bfa60da5c47559f248793eb4dd1216665201762d3b64c4782cf1175ff2eab9c6868b764d27a8f29e882beee78db130563114a1c8d91f125748ea0cfe56361aaa55b8d45a507754d332b8e9c252728b103aa48c1d5243c8e9e9a9879564f61cc2bb8cb3cbec982167859524f78cb374bb95056505acd22f0cd2890162931d4a200ba1e8490bbae0b521ff93bbaad8ed3ae62d7246205f92f8a7180492c398f76674a1a77d4278ee4117c11f001b016dc057c4d8665e7b4608e7726c727356e550a6974a4a0fa77b6677a40ff5683712a24d066d00ec14b2f926ea6b0b01b16f21a28b1ac2bdd05f4c162cfc844fb3ee4a4125e84e0876a77ee05457931550cc6c96673cf9d4526959719170815bbacdc97bd629924ea99731238be3f1c27a6594182f1944af3235ca8ab8ca067a1c6628401b4cbd665457e01c5fb6fed88191b24aa65e08c4bad30e5f9a00857aaaa0092302090ce66cbe192089896a524074c4a4e007e8a466a741417d7fb4f6d85e5c656c9540075258e3e1a0b1483ab482ffab6be449be33d0369c637cc526ee663395e092051e278e6aafc2e70f707017e85ab8dfb292a0d20eab39a773a429cce65a7f236612f633d79032c88b58af02651a1a05166032a446457fc2c8a548a60af745b8d762a1118feed7308af00023ea521d4a78a1e4d44cd266aac096985cea3f490989413b3e9cc047cd2c1e7599a5e3e1f081c647185bd819a9d7764a991e0a04db7a375102c5201527c9d23b242ac5ba5022ce8afcc78fd3a722bdc69119158898e405e68724889d6ee56831c1a2f39e507949a998e9fc3f2640c861841ac7e5ab261b563922109416ea2c4e071b4a1e46bc6c87e03b4e58bce9d7cf40a78407e1f44076f8166dc809a933e219e084126c1acf8a8e14e570383a454d0043c46b5e940540ff1f9de329321dcf7b179ca7adbc33693dab233d5d809332a5047839e50b1f20540d3d4a1908dfc64869937ab9b1a4bb21334826b449db24bc0a85a26183e870c39ce0e38372ca844aad89cec673713461468958b7e24fe3873670eea199eac685e9e64732e6070efe23ab892ce3e8b2053f0c1edbe5a46b1d6d839818047b0f2ae2150b909a3e6cc818c9819e3a156980fc2aebb172ac57a8ced24854550532249d827e798a83916bb4271aa841c5e76b49be014651b59f151092193cce682e1ad237818746724819862494633a96217581bba6a8e1652829ff0c128111d5d5d6b5bdc707ccf09e479e561aede184ac631cc7f19de60babf183cd6e6e3d3a80cbb398c58a147767da3d5e500c956083ced0699a850aada1f7b558c86778d9bc21b02ed4f6beee8a6267244a0e87687713161195d94f6dbf55adb0eb95967880a94c358579d945c521f19f361d68818a8cdf01f0a0f4a125e96f3a984d68c8a8a43cc8bd9c64a1231de791e2754928c088a519921888d460d7c5548e7c9f88e360c8da46e7616865897aa4ef14eaceb7753103103c343358398a4530d8fc86a851999f4e49b30e365044eea61a4e47524198d0f9600d8b10155ee33da006469ab55782c46416195f2a153c264ff1d7dbbb72ca01c26d11aeaa642fedadaf88a7478acca65515ab881719c8200d8559e3a63b96155016b625cb61a09209ab89cb08b444da5e6990f466e286047a72b1073c67d9e5cef88ea2e2c3713f6b1c1bababb9a1f2698e814c6ef0f4bd8aa72a7daeb41364c77831f06720b34574dc550b6b44a3550613c51db1823
InPK = e2637b35a9e43a2dd25333c125bb90407b7b1c0c62da269efb13008434d8a8f00d212f6198d693bff0062482ba182ce12bc16520d6928e1d6ea54a870adc94396e2f633e6a9b024f8878c64c8af86164fb6561717369db940d96a1844a7511105271785a8600fd062ec6e3f853a584ae238e7fc948ec1e3b2d1e24a679696eeb4a6a8e3d00f3d4428043b81ca050d3fbd03c036b400cfac70ab179eff09232c40f374991bb53d53f8c930e241105b31391fa9a65142d0c95b88b06c12c7c195296f91246e7687034eca81ad9ad1d47fb6c006e2245ebe8a179531c446976fe39028a06a1cb6451590f9c883095b9d543e36b26bd1506dff3f7eb9d79cad5fc62b106820f544e3688f09a386c07f0a7428892a80620f3da33bf19e595ac79af5d58cbb8b404862fd7b020e564a2551df746dc880b67098df5732eaf139adf20f41c8323c71e378f2e35544c12f446dd8536445a993f25a028cc3e106c9410dd5ed2f5f1acb1a02683e21c357153c056d2e755731f1aaab7dddd9a75cc159377ceb26404efd25e6676d946ec388a4268a1ee7317f209861adf78126f025363c9254839f465fa5e9e37098ebd8f633a16ee310a9d512fa922dd25dce24b364ba24388a72d40eaf13e4f535b61d8007690483f6aef6d4d07819744091a0e4d4a3ac85ae52f04d530a937aa0c81a858d7b38e7a4281ab20f186890d00bf89590650a5de283a37fcb2a4cf85c658f4148e24b478d8225f7e0ee0135c9e39568a6f8292261d856b9c3878741a11ac9d39aba68cb714292943e44aaf5d9d00385425d9407f99ba6a7743e9abd162c80895ea9585b611a205c90b9ad2188e6a903f5554c4a35996ce266a49371a4fecc68660be35055fe1f8797a5f6dce81e22414764c44d3ad981b2eaf415169855ebf5a4de3904227789c58d2a34a0c75e50668dfce4e4f2083a693a607370d5e9a79f943609f94663cf47c94e14d5708346b33ab51c2ba91729206356491cd57afd8ceaa0d3634d3257de0367110f05ab7253c2130989b9575887e0cdc6459f9e3b61d72416242e6c2b02a8ffdb98e5c5f6da8e7a13a7c7276ce47e4bfba1cdb000ce070a4bbed57413ac7e5110682fe86b0c5791644be6a7ce6169bca6bfab174b734918da1ce4a399a903be6e2621ca4a86f90e0bc4750819be2cc4603c4aef178c3865c9d858ce8a1f0519927fff327b906cc6e39a4238da0c7061fc4c8240388acd039ae8e7d68990fc78f5061362361c1e1869762ce6a066d24aa9ea4f8468112072fd16f8b314c5fb4c032725fb6729812fe9bdae138b81aba3abdee0ff740fd9a5ffa18205b3307e53607e90e7894767249ae95a436ab71798e1b5b48f4117cd56e3cf3a4912dae43bc63598a78f2ece536cbbd4320248df43cb845169a01981ffeaa2e9dfc17a8aea8675cecd86e7e9a544bddf12af07652cc4b2610a81871e66eb18e643fcd267f99b731ac72258ac4aa66a41a1cead40450876115119133449e2e5535b008957b7b6682e8271a9b0a4c0b4849fc1fc023ec529d2d6614d7e860587925b1eadb3311c90aa1597af55af1beb62dc01867dc0b932deac47adc91d7c1d93968041a1edeb5808a8883f65f7d11be85b8435d23482c081a9d6d3c5693a05aa66186620ed46a23118552673c96820a6f3bb3aa9e51c3a07b26d497c458ad219c5588f461311bc8bd702309f9b44aba430d81559989140f95982e871d502e02c3f161399a367910d526a2063b4892b507c0611d2d8d6d901e318e92eda13ac2c14ab3a9b13129552c00d529b975c1a8bfa0b55bc77488424af77b97d63fd78d9998158e51a297d286156a99fb6a5112ade63a1085228ba7de53c7c3f2d2131e510002ef92cf4c5a45570e07abc094ba294661e4cd96fcc3a7a1bfba84d1a2c8d0b2d550e20fd963d3100fa9d890540cacbc2babd97b6fc4052dc4d4abf77e6c5b8860219ed1276c9d5c566704a9d19e6f54d8ea63315079839a042ff0520797ce78b1489982c26aaa463b20a2e9ac710cb08473e79bd134416357e5216e3e644b71d7182a121dc0f1463e22aa44cc4f6246016cd1af2d119e82abbeae7b6b1ec05e38acee10fe422051c448a14a71a23a98594258d9525544fe697d752477c5e01922706d2ad10351262a32cf86859a180d7f2185bfe370663c9fe81b419ce52560d9552b95f013b31068eb447c528a48c53bff387575d61dda46a9499a0b0d59602591c31a7a20add950142d82719b08b460270b207e9a03ed91eee0e5d8203e5fa061f8e624195f05a4e4e9376e9dfba02d14325ec2beea8fc0b21e67e8b671d8a194e1f9367ada2c9a096c9a6d5c83ba9344d2d2026138ac89940a946090171fd868310fc29f2996b1046910a754243db02fbec676109fa25de969f3e626646209d38b9b3bf909c4d249e5ae2dbc119d779270aa3e332fa2124506a80f41c323a7e1a9486a0cf5002d1ae09f798670d981dfa07a313a254222a131163d596443ca8697e4990e0fd3c301e45874
InRec = 00c00020000400038000100004000300000000080000c000000008000080002000000001800020000800008000000000000040002000040003c00010000c000280002000000000c000000008000200003000080003000010000000020000000004000240002000040002c00020000c00018000100008000340001000040002400030000000034000000000000200002000080000c000000004000000000000080002000000000400034000300004000240003000000001400000000800030000100000000080003000080003c0003000040000c0002000040001c0001000040003400020000c000140003000040001000010000c000000002000040003c0001000000002c000000004000300001000040000c0003000080000c0000000080001800020000000030000100008000340001000040003c00000000c0003c0002000040000c0000000080003c0000000080002800020000400008000000000000300002000000001c0002000040002c00010000400024000300000000380000000040000c00010000c0002c000000000000300003000000000400020000c000040000000040002000000000c0001800010000c000040002000080003400010000c0002800020000c000080002000000002c00010000400018000300004000280000000080003c0003000040002800010000800030000100004000140003000080001000020000c0003c00020000c00020000000004000280000000040000c0000000000002400020000c0001c00020000c0001c0000000080001400010000c00008000000004000280000000040000000020000c0000c0001000040000000020000c0001c00010000000004000300004000280001000040002c00030000800038000000000000280000000080000000030000c000380002000000003400000000c0000c0002000040003800020000c000080002000080000c0002000040001c00010000c0000c00010000400014000300004000000001000080000400000000c0000c000000008000180001000000002000010000c0001c00020000000018000100004000080003000080003c0001000040001c0003000080003c00010000c000140002000040002c00000000800030000300000000000000000040003c000100004000040001000040003c00020000400028000200004000300002000000002c000100004000100003000080001000010000000024000300004000040001000000000c000100000000300001000080001400020000c0002800030000c0002c000000008000180000000080002c00010000c000380003000080003800020000c000040002000000000400030000c000240001000000003800000000c000180001000040000c0002000000000000020000800024000000008000140002000000002400010000400024000100008000180003000080003800000000400014000000000000100000000000001c0002000040003c00030000c000140001000040001800010000c00000000000000000300002000000000400030000c000080002000080003c00020000c000300000000080003c000000000000300003000040000000030000000004000100008000380002000000000c0002000040003800010000c00000000200004000080001000080000800020000c000040001000080003000030000c0002c00020000c0000800010000c000280000000000002c000000000000000001000000002c00020000c000140003000040003c000200008000200000000040000400020000c0001c0002000000003000010000400018000100008000080003000000000c00010000c0002000030000c000000001000080002400010000800000000300000000180002000080002800030000400008000100000000280001000080003000000000c0003000030000c00030000200004000380000000000001800000000c00004000300004000040002000080003c00020000c000040003000000000800000000800014000300000000180001000040002000020000c0002c0000000080000800000000800010000000000000100000000000003c00020000c00030000200000000140003000040001800000000c0002c000200000000040002000040001800030000c000340001000000000800030000400008000300004000340001000080000000030000c0000000030000c0000000030000c0000c000100008000040002000080003c000200004000140001000040002c0001000000000c0000000000003c000200008000280000000080002c0002000040001c00020000c000000003000040002400020000c000240002000000003c000300000000300003000040000000020000400018000100000000380001000000002c000000008000300003000040002c000300000000340001000080001c0001000000003800000000c0001c0002000040000c000100000000040002000080003000030000c00
Key = 489c79a48135995c4c8cdeec1777a79cc68bfa7b167f21a25e92945b4004634f
InRandA = ad8ebc02b5c27c85c559292964696c2e3fd406142102d74d8ae9168131abea968da1715a08c67bed550789ccc9254e404045d18a89d4a4696996a5c5cd3c87cfc3d6e92985973d6cce02ac765bec09fdda16a4776c9d92c75431121d1bd453b8f296dac1a5538555823b20f2999cc416e62eaa90a3a2788d877d03b69e399dd089c7778e4d70d831e48a9c371218478612a2ac8eae6c8278956b1aecb7874da681a14d5e5a95325400ec0341f5d58767d0a7798b56bd0882d35b1fee076529fa8a13d523a965093178959a169de1643611870f869069de2c1fd5cdc514dcf626d5da45e7a34c9ee648295890e01f222fd56089a99c6c1b9ca947da5ea7ca32c7a0faa26bcf6ec390ea439defe6a19daa689cc1a1467cfe75d9285931bbc42f2f21d802cea83fc1aa27500762242c6e624b396c499dda561aff040d6f265760ab4d38256352b682682f90c1f9aa1046838ceb916061a550370d3830c0317be41a8f8853406a8f86bda08f79b3e31f8c7746da1c62553ba706020ede82e632a9061de666a8b00bb10e5f44762a99e47ce09c68d080b931e5c34d4be3dd8a7b56cfd762f610c2a183293268258082873779f418d30c7f3517e192236ac6e208c994ec9acd82c52e85f4642c0626763484afe6160eec7f8e2fa317a1ad89ee65c7dbc18481fcc42a757f3d7b48a90cb211703f1ce112e4822057f385b497b0325d94594b66997e5dbf972b9a70b010da0363b79fad6841d4ba8513bcb728ae50e3bc7550630272a5e189715fc198b331de8931af19a0bbfc9e24947b97c0e2a751aca732389252ee53d1093bc175ec0035013ff2431e4fe3da60cc769c0bb515aed63601e824097e750c3587b0569b2897754676917c7e154aefb5f829b60e71c8beb534be1f39a0cf36520a727204339796bd24885dcae7c5e18ba40ea3c553e193a10f6255734a6bc6e171f9898969d8cac08721bea50ad906b4f8803c695e76c21a46b285a728d3f054bede0b1b72630a5eae82838714b26cf35fc0027fe685b1c7d4d422d606cd23bb68e3fa052b5504b243313892e4d1123dc6661a4bd899cf44584e975b14a8dd6bc4c6e1a7b0ba1ee7c6cef815e561abee2052462e6ce46c92b0bc1c717e0aabb1f09c21272df5f6ad650d0e0528f04c652a6a4b6ae784fabd51a3395622dc274d486c36b47d4be3dd454324e12fabed0f6761c9712d1ea6e9224653348202e4000013d4ea0300b6c9bf6a40ef32c1429c28a24a7b8d14b36a15c17896ea0ca047e7c6609177c2ead50053224a5ea12dfb23095b905fd88b422646e991d1049b9a358f88ba76ba3a24a4018594546c1bd5d4f5ab19daa88cc33f46c6194e3217b00b500290ca88c2200a3493ba935949a9cdab90c477b6717ea0df127097e73d4fb30e659b6722853d468261be609e085735fb15e075414cded0e0825ffaa99b0bcef49fded751d6ddd63d37a4f787b74094b356ffa3b5d920749990700a8c24ac573ac9e87d71d02fdf7362d830ac8080f7212a206754fa3bbd1ea21b5195d53ca67769ce53c4451020190b58c821aa5ab9909d69303419501ed9098fe11c048fa1c48d816334468370e5fc21a02b0bc94d158dbde43f9694f441da613252853c7f8010ca98720eaef82599dbf5a84b3a125eb42ee22af05a495077499d43ac084283d2813b6c0fc268e0b432d7ed59fa06187320ef49a7501aa648d1faa1b1a5e0ee2eca253629ba167a670d86587652fcca51482f704cfe71455a192bce7af801994885a34a3a5a063c79860cb0a846b75caf889ac9221e41d8828a783d9510d830a4a5ca7074ed5804e4d60f24eb90a609f07bbdda2df9f7fa5daddb1547582a6b5a41ed2350d0a4875dcc09c8f929e951f231626c3bb245f498c8899bfa9ea610522190b92ac091260e1489089bc244cd57c75b3813d35d84d48d120531ba07c9aefa76733a93c140a737223e7d58e57705425554b52be20ae22c4e69496e5364c906f78f3687c7f0840eaf70b233557bdea0f896b5ac60b9494fb370aeb69d2698f3aff06ebd85ca19fba82873a364b6671d887faf673586f551890b116bfb0541bb55da875cbcaa0751e05b73f20940a26036c1c2710283fe44bfa8b295528212a5b20b750e787465325adcc469189ec8200e866b6961ce8c8c985d18f6bca78540457bd3c12a4de82fca18dda3e6a1ea38336a0d9d5f52eb52e831afd7d7f23a2c06295cabd38bd558c30763669b89289c97d8dba5ac005fdc87534b32488eefeb5148262202db92989c543b2e82105159cda8f1948513b2a28b7fda1c78ae6c1269021a991b91a20ad698e3105cb58e2ecfab1a8d61a904e63244596acfc89f8b146d966915237bd0ad0e79e2cf029d8087d25056b94a699f6684cc83646257f4d033c7d3a6b565aae8626706a80fde6e595b7215dee1e689d7865f5b6b6fb5a3ac90d84584d15e862d2c0ea9ab60e642c76592e7dae26972dfe414e8e5873c6c6f504ec27f4a91b7b5c4aeb900e1b5e927ac57
InNoiseS = a80b21a95b81047b96b9897ff01246dd9b46644d94e9eebb652d84bdd21a45815d7441a863e381121a78479f8a8b8ca9b3ecc170c8ac0630b1dfddba2f28a373471cd809001b36ea92e6291e26da1bbd469d526e734f45d78f2c6a840533b955fc36330f3dc865d5b7f9d6110b2b3d0eb92f34b9ae344ba06f04888b3202c111ad4749a2b923aa08528eb6a18a08719b06f4793b0dd2c958da1072628fb9a410bb7c5c2165806a718ba1ca0850c191230083928062776069b14562d513e843be94ad3e476b4c4239c1d52fbf900d2b00cd3725dd5111c238ba16a61314c59e706885aca57fc505fb9dfbe6ce6829bed6cc76e9e1b9af52805a737e4baf2f37ebde562ea01172fa29c27e4ed7244308aa253fe11481c90c9e762b11a880a6590d58ed1139f62ba60313f4afed1af24c4764d79c89fda62d06fcfc6258e88979f2559ca0612f845a5c3d6f6c5df309ac8701cdc21a648996f8d8ee97c8d894382b3994b3357afc5d06682e1095f25c1b59be76a316159cb623f04b494deb258f043f216eba710e6e9b0ee772432a45456602942a39f1912ad530b1d3d0b740e3f581cf368acd463a23d3960066d92de33b0a4a398ff673a719b52e15ac91b6a51aa8144826fd657bb517cb65e6e9782dd30a324022bbd7cd8995a5346b32970e0ae9be9aa79c91826b2c0e3c87c0030f72149ca9a77a53e946402e291097158db12aad04dd0c839aad8c220f207214cc87a07d057a81e37ba81956ab24554f657c124e10683af65fea15531d03f1190ebd0b0278089cbe01b019b194ae6ab8c9ef2c8b82e16ff1a4aad24060a62c5e89a3676d12fc1f1be3ee0e552c15808104919e64000a92d55800486af24632c4b02e631a5572d5751385aa95d4b5bbb71ebd56548a6f4a2cbcc33485803c90187b227ab2829e732b8ad15dddc3450317a966201f4ec3d70a3d04ec9a79a2c98ef2a3a693672ead1f0d20e42008726320f1ebfe162ba0c611b03a32a0c96260443ddeab0b04ff9381f14363a6a4e90b45a356907196cfb845c9e68c91d79d2e74510f5a2556605b0505142b0549416e3f8125c65afdad22a88620a05fe34a998a46ba57043488c2102e23da22f18e680be20702d326f8a86ae4bd36d4ed4e0f53fcd9d59c0cdf6a5cc80325730a513631991e420daa12b9f191af12c9b429298157754cb7ead1be85f8e826371954bb15946fa6620c8d63c235e37e7cad391829c258446522e30a60f0fa7a41c05eb0b2fc8faadad38ba6f66ec70fc62b2e9976a1d56bb2b4b26df54621f26b75af4f5030a668e211d58d36688e10a692c541648214a9e8037b86ec2009f2e6c5c0bb4c7e91db3123818441c8675d672c6e7cfde43d359d39280a974bc3e128407ca6e2883f21bc612777508f32202f2558b5b6224b6d4da3e83c9d3c582f7ab1bba82c904a1a75d6668ab0ef8893f4c24e305063e6d85471ced2d74a383451ab027613cdd094476538f9d03a55be9e4d0788099a3a4acebac42865ae436e55df2123a9425270cb113818640b614f8c487966904043d531b58c44b50571b1d45e04b56c4a0332a180f0006e3da108a08978159282670ea10b4e4e89155285bcd0a4d90827f845683b5fd708f0aa9541af9e304b2eb87c4b06f5d483789a621b5431384d7615cff8579ca2a44f157c6882ca6d15e213a9c8fd85015bf8d55cd21d274c442b66146d8dc456718599a68e8d57869e5a4ca4d00b17996c2bc483e476421205e6095594f5a8908ec8c6a28c118b9f2e7794c9920b928f4a5729ec983f2c5ae4846c91d50ddf2b90f6513949187900aa8ef828d4640012006dccfc7a225168165fb32b3a9d535de29310fa669aba94faf0c37d3a32463ec711a474e1cb20c15b36845ee4f6785d6d1a0eebc771d68d282ae2326933211fb91ea08b045113feef903bcaca3ffb6898f61815890b5a09cbe2413e5394f3d65a42250fae3930ddcd1d3d63bd26714640b8ae4cfaa3e57f0fc446ebc6e0822e6aeca4625252591568e1f80aa29a0679e65d9c6d19ea2f388c1a1a526db1f674f22ceba41412fa247b192eae509ff831be8fe55433a69570a7b3b24f1c8d5b443dcadd25a11f0cc432136c79bea5fb5a83de240c64d0717a7299ce499496e71e675c20428834445aa99db4124df4615865b68555c8ae0b021a824324a81ce0be995352b84490ad84413608c12dc2a00e4a53bfdbbb403a2847dde4616a38ed47cc8b04334cde0269ef0120fdfdaf795eec3b98924cce1a3924198e36dd6bc638faa01d76559942508e400c5f10573fb98187a562ca966dbe1b900043fcec5d826d17eb4a1e3790875d05baba956e6cb9d88b211bba112217d01ca67e83e3f6ae187e82e7c3398c127f894bedc489f15f6faad152f2364ebc8d63009e241d01c2db7bb9d6487de303a3915c4699c3e9857d8403671d2a774fe618d34b75560e78285f11938a343d8f5663a396c642b8dbe44aea56325af044979be3cd37b0e3b69436f45d5e95883a47e09d
InNoiseE = e845be9491fc0c92163b96787e80bf0ed9e369841d76e3ba6a87548fb7999f66d78d96a7d296e777fe3db2c3033a11064940d950d84f01b3d0aa612119d18c200225f7d554a8f2c6c921c28e67efd92587a0f084578f5c36473500110ca8a7415c55750a75f004823d1be0cb09c6488918ea38c3778c212e2cd80081d95950c3fdc1cc61b24b5c8991069867d196189ae04c893be3fb51aa794abfe72b33e48ea2af932238e8747b37459854e30c84d223faf5cbf0707ae958483b3553b3a64aea4afc97eb296078007e2bb480c911795eb3b9954a83fad85d3e254f434c3d1075e9180b32fe7b2e083c0bf3469cb2e8ac6aa7c59645c9d0b3e2fc78ad19014546a545d7ad64d0ef2804eb9a8495c4805de8049c278ef24260019b0a1dd159055ac289067820e2c8cfa1cb7dae90e57072d0d14921ec2ed8ac2080011f004a95405c5167023b0e6e9ed2d0b15b9a0008a6aebd9677feb4cf0d6f904dc0bbea8ed11601c8bea66581c006e5a37ead62954e7ab810537f06e7d1210c80ff844fac9127c1b2005d6541dbe821e490e008524671a653709c249db99940567c4292166bb508984120ea44ae4180f62365d97b3c0153defc41099a5715a4f564d1454c172e3b8366a9a8b5415c99a9d60f6f1fe5a06dc58b7782dfe727f2a8932d45f5289e00ec07f6932d4a44f1e32bc446e9a69e611bc43b3015059f9093172583a0e2e18a2a557fe8690eb852cd1adbd1eee0e8ddbf9de930658830262e97ac30ec3893945485040d5caea90c3510b924a9ca842f281260217e2aa49a7155849c13b4963c708b71ddca47f9849f3347088519a8437462f348e7745aeb40d2eb36a2224617d85220f18f2c99d4c54ccc94a1dc1e47988d95470c925204014b201065b67c785d2a6f23289ad89df746ed90b1fc5a23c8be594a3943726d3c47efe0b087255413ceed195fc6bfb32fd8640b995f382e2d945645a05682ad74cf9ac2e3e9f13b958f89a541edb34558363bcea95315d9e7184dea7f45c081e1ed74869685685148164e4aac81747fe43be7d550a06885552416dabae41c23c89c4791e2110b07a3b4007e2a2d2d6dab709c384d09a92f91316225ccc46980c5ccbfc19bbc91f2d818f557f2f133780367a4954bd1fc8121e86ef57f1a59419d20162baa6b465d61231f5806dfcc373b8510b8d5cee65a09f932c54c71212c3570306baef65a6e8fc0e533b10e0abaea9105b3e5daabcfc82c92550c535c646e84aa4ea50ba7d8c78f419f61d4f6d39f1daf4deb0a48136c6a5d65f2f8db6612ec654795241c0543a1bcc69f8a65dfae5c76fbfd8c105a056b5a5d7e586087719301ab6804f2d5c1988a420b45f58a3e717725ec36e9c1877bd515c814da53822022763808907f4c56384131babc125b1562884a538cdff5e0c137e61b45a40de995c75929a8b1beaed8817ad64b15a823c1f6345d0924958310f0690c576a459d572b32496cdc53fa424cbed92b97a4214974ee10daa7c19d065299ac11151a4eeae4dc6771f642b0661c999ecc96ca58a0c7e80a621c6b32d1046c38ab9368269cc61a48e532171606213c5d5bf4ff6a19b4d36bf85b12b830903ca70576b276195356c03caba1cac6d67e923e2b498371985664cd0a15b46f1253822c3870927202f08dfee8d315255d09548ab2b698c8d19d9b2166a496c4431b5e99644620ac7663ba3cefad032bcafd77559d4fabdc71451c17f074ee12ad13443698a06c758c44afb28190245b221874073a7cef2d8ae46d5d2c2ce6b7fbd0c92978c1dd6a2bba3da1655bdb9cc09c0a24d1c4822c3ece61708414f996500ccbf0790e2f7f9fdd739c7aa7ae1d0be4ba4181910f9d339b6a1667c115b6b6884dc48642f551fc7822ae8ad55d6cbc32141762f1da6ff967720622daaea75455e6a999535763a17248426532511e33d21e00e784258a5079bdef43068acd352e7a43b269ceed99ec518db908ce55dad54c46277da381efd1a147854b492aa31b45f86f06476d6b2cb078cb8d137ab94c3d419dc5b67b6051286c9feb1a9a24d92d8ac781dc7c7b458e30bbce43a18ff2c4343560af9109cbdf69b49ed0ce24304015fb0adb88c2e18f0e50cb662f5635f6240ea0ed7598f4ef07da6d21ba975e9411e39968d5461977104c283ac14bba833cb5c112c699c25064bb22f0fb80e11cebcc0e70a90556e61399049e5880f2946e3425a4330d8ca8aae68d2a4160f1436d0a37aa91c3651bb4bef354f82404061884e6dd55ec591bea4a52b0e4096dd04514d4cbd891495da4d113381a756171d00e8d74d42d2a06001812fc63a10731918076ac892573fd17eb263dc0490615a0412bb38e793eaa146758b4c08af825936732f0bb8616151574c2294b51bb9a1bca28fbc7e29b30e5852c910f40c3d920feadca804e7569e827747ae976b6e5852a76bddea504cdc5bbdbaa06de2aa78686f0973845bb7563fc3c03eb6fa93162b40f56d50bab801068dfc3934c4e7a2c6708c9057e72
OutPK = e092dbf9d91122e3c8c9b32888abf88fd30616761cccd9e4668c8224c749b688e8f27683d5ca9bac627d876c0ce8f16a872b190b69e839729d51b3a44742af8690498480044eea562de9fc9223254b1ee4c0047763914a21c93876e8e4a8650834774d4eef5b18207f114cbd124c158bae99d658a3718ad0dfd85504815a88808662264a90282e6fb9ca32863d5c789172ca65201704d2e94042aeef4e461ad19d9561abbbc09ca279aab71548b219dbe15199131c7eb9427ef9874297dcc51d83dc1d57d0a9260350a250f9d9db527e4e903605d1bbec04329288f081099218f715a8e808c9a222ea9582b6268a9909a357f4dc1d6d5504253adca14110e416f5aca00dc6ad747dda9ea34085854589062f557434adc9656b1357c550e972c86005e41bf08ac8817c4910813bb44ec3ea63a9b7acd1882695640fdcdcfb943baaa0d36a874b329c43d0dc82e7e6b1ae662abe23cd8eb1382c3241f2614894842a43e969805159846a38715cd98244260c604618eaefc89548648fc6d5f23f28246c033d5b3110267e0b25f6adf9432156bd6b9dc42bfec7d32b5b1abd80d19ebbf2388ad3af0a55e92da8a311434ba38a8b3d6252a7165596c7825e027ea95f619df33413619dfaabbc4b7119a9a8227044cd7827046b2e846ccc12bbe58af4d17d7957a50b6830c55898d220a3cf6500fb1d901380452209401837aa9c6c3403d71be9fdb43f5f64a5b866aeeb559833e604a463623dc9b5ad397ac8e3e7b0520ac610743a6e39a4a0a01006bcfd59e38bed07c7360f772c45d1dedcaf18e2593566d646292911bbdd7d632f57565712765fe90b0109ea3db99da61bb5422ea15767082184e221bbdb09e4094e58ecefff20560866c6eba6d1d7443180417ac8690223e9dd8c99a18e442e80cb4ba0e0746f644f34996200d8db57e6d7927485ae487166665880263cb1bcf28e1c4977864ec9a0b4089e5871be09e6a89879ee48aa415bc0a1d914a1faac0c91ae3889554e594842b696b293700651c0836e081dd250b00e5229a2ea113907b1a0a39b5a4555f66b4baa5dcd1bb02ff997c75d40c98a13474a1892ec463cd2eea565ea9c26bb987613c5aafed27dd42eaa212a09a01a322b80ff568f9d16c3ac70c5b958b7cf16fb9a17313858257133290a5873d34b6957da55b8a5bee2ff2a4ed363b12076c033746bc5b06a9e9c41dcb5780d0d29c0e73ad4fede7582256c1b3bfebc96245af8f97d6655c0606b1bf1bb8a27c719c41117402f9f93fea5bc0be6bdb14b96657de399a1c1206da328342b2d78aff767d7116690b16e0a9385b131a08e6230d0306c0bcb8e1685c1f857ab98d6f865080719058915beec43539640245cc6bd478719c39a691099c225b966ad7a838c4c08beb4033649288bae74978eeb06a6e36486ef1766955e3c31a525f377fc6abd050a52ea3e383ab792606827f276a8a736887a9cafb80314107e9c53d45be5ca85ba0c582683328839a2dfeb044abf56a32d22a4146b7aa7c7c926404b12645b10dc4013058dde023068f60501d9ecb8234a08992220d923110187f26b7b946c683b0d9c64f6ca397f019199ea72e9a13e5552b9b16c95e66eed44149e980c10a46b76c9451f8665f69a716d7bd5fe1858e677509a1c6ba3a8662aab81e42d7e39652d5c09141e8d3899c3c15a4c41bc1489d407ac1e949d37b1d359b58b6870c87e5c885880d8bbf2889b634ef21379f8b9f9a68344d74c4b9c5ea4cb7be919ae0354a189064c0a013c2b655264140c3dc43a812c762d00db994a5cb9a98a35cc582bfaca1c134636a76393ace07e46167aaf6ea22d783a6c8d0d891b5669b711ea92a701a660a2e7e1a368a1f65bd63a8cc2041fa30a09108c002d198d10cf5d821628a8cbf6ca45ebdd5a0018f8a832684fcb91b66f03c0bf56b9413c405457f563347f2928ef63bd3c6531e6ec412ba914ce9f2e576c913af8eabac93492ac2aae23233481afa0594a02cd6a3d7451eb67ebaa17972b6c749e765ebf9b1fc8953eb8b912ba2a6aed334726fe3b37741a26499f62928e0b460da43586923487e2648beb2c2ca59e64a987100590284ab2d25ca215c8ea765d31372d63547627221dfe697fd2db5e6226ac8ce52d0155604ad8c07c799a56e828bad21400421a92da4d455172c2ee099aa13f32a0fb02eac95487624c888eba13210434f52505bbd3672e83b2157cd2890a80e42475bd6e4c590ca9af555dad24e2694dd86d923a62fe313adc2757e195a2f7a8a268d1014a0bdc5bd4b6fd2c0a6a77468ea8bab7d0abb339ad9d186e172a2dc40d2b12cc631c0ab30017ac54f61ab239efdf257ac26ac6e3205ad84e5bc9876c284326430baab511444460dd08fbc5cd7c5ca2e14185c8148552aa1bbaa319b2cc937f17aef4711862e944f2a9360c5d5a96c6baa7f40bee36ee65119c243e78a08eba11e48c109f652844af9837056635649169f2bb3d9dc209543907a6ae6d837f68d670bc7b0626b86b0ab7
InPK = e092dbf9d91122e3c8c9b32888abf88fd30616761cccd9e4668c8224c749b688e8f27683d5ca9bac627d876c0ce8f16a872b190b69e839729d51b3a44742af8690498480044eea562de9fc9223254b1ee4c0047763914a21c93876e8e4a8650834774d4eef5b18207f114cbd124c158bae99d658a3718ad0dfd85504815a88808662264a90282e6fb9ca32863d5c789172ca65201704d2e94042aeef4e461ad19d9561abbbc09ca279aab71548b219dbe15199131c7eb9427ef9874297dcc51d83dc1d57d0a9260350a250f9d9db527e4e903605d1bbec04329288f081099218f715a8e808c9a222ea9582b6268a9909a357f4dc1d6d5504253adca14110e416f5aca00dc6ad747dda9ea34085854589062f557434adc9656b1357c550e972c86005e41bf08ac8817c4910813bb44ec3ea63a9b7acd1882695640fdcdcfb943baaa0d36a874b329c43d0dc82e7e6b1ae662abe23cd8eb1382c3241f2614894842a43e969805159846a38715cd98244260c604618eaefc89548648fc6d5f23f28246c033d5b3110267e0b25f6adf9432156bd6b9dc42bfec7d32b5b1abd80d19ebbf2388ad3af0a55e92da8a311434ba38a8b3d6252a7165596c7825e027ea95f619df33413619dfaabbc4b7119a9a8227044cd7827046b2e846ccc12bbe58af4d17d7957a50b6830c55898d220a3cf6500fb1d901380452209401837aa9c6c3403d71be9fdb43f5f64a5b866aeeb559833e604a463623dc9b5ad397ac8e3e7b0520ac610743a6e39a4a0a01006bcfd59e38bed07c7360f772c45d1dedcaf18e2593566d646292911bbdd7d632f57565712765fe90b0109ea3db99da61bb5422ea15767082184e221bbdb09e4094e58ecefff20560866c6eba6d1d7443180417ac8690223e9dd8c99a18e442e80cb4ba0e0746f644f34996200d8db57e6d7927485ae487166665880263cb1bcf28e1c4977864ec9a0b4089e5871be09e6a89879ee48aa415bc0a1d914a1faac0c91ae3889554e594842b696b293700651c0836e081dd250b00e5229a2ea113907b1a0a39b5a4555f66b4baa5dcd1bb02ff997c75d40c98a13474a1892ec463cd2eea565ea9c26bb987613c5aafed27dd42eaa212a09a01a322b80ff568f9d16c3ac70c5b958b7cf16fb9a17313858257133290a5873d34b6957da55b8a5bee2ff2a4ed363b12076c033746bc5b06a9e9c41dcb5780d0d29c0e73ad4fede7582256c1b3bfebc96245af8f97d6655c0606b1bf1bb8a27c719c41117402f9f93fea5bc0be6bdb14b96657de399a1c1206da328342b2d78aff767d7116690b16e0a9385b131a08e6230d0306c0bcb8e1685c1f857ab98d6f865080719058915beec43539640245cc6bd478719c39a691099c225b966ad7a838c4c08beb4033649288bae74978eeb06a6e36486ef1766955e3c31a525f377fc6abd050a52ea3e383ab792606827f276a8a736887a9cafb80314107e9c53d45be5ca85ba0c582683328839a2dfeb044abf56a32d22a4146b7aa7c7c926404b12645b10dc4013058dde023068f60501d9ecb8234a08992220d923110187f26b7b946c683b0d9c64f6ca397f019199ea72e9a13e5552b9b16c95e66eed44149e980c10a46b76c9451f8665f69a716d7bd5fe1858e677509a1c6ba3a8662aab81e42d7e39652d5c09141e8d3899c3c15a4c41bc1489d407ac1e949d37b1d359b58b6870c87e5c885880d8bbf2889b634ef21379f8b9f9a68344d74c4b9c5ea4cb7be919ae0354a189064c0a013c2b655264140c3dc43a812c762d00db994a5cb9a98a35cc582bfaca1c134636a76393ace07e46167aaf6ea22d783a6c8d0d891b5669b711ea92a701a660a2e7e1a368a1f65bd63a8cc2041fa30a09108c002d198d10cf5d821628a8cbf6ca45ebdd5a0018f8a832684fcb91b66f03c0bf56b9413c405457f563347f2928ef63bd3c6531e6ec412ba914ce9f2e576c913af8eabac93492ac2aae23233481afa0594a02cd6a3d7451eb67ebaa17972b6c749e765ebf9b1fc8953eb8b912ba2a6aed334726fe3b37741a26499f62928e0b460da43586923487e2648beb2c2ca59e64a987100590284ab2d25ca215c8ea765d31372d63547627221dfe697fd2db5e6226ac8ce52d0155604ad8c07c799a56e828bad21400421a92da4d455172c2ee099aa13f32a0fb02eac95487624c888eba13210434f52505bbd3672e83b2157cd2890a80e42475bd6e4c590ca9af555dad24e2694dd86d923a62fe313adc2757e195a2f7a8a268d1014a0bdc5bd4b6fd2c0a6a77468ea8bab7d0abb339ad9d186e172a2dc40d2b12cc631c0ab30017ac54f61ab239efdf257ac26ac6e3205ad84e5bc9876c284326430baab511444460dd08fbc5cd7c5ca2e14185c8148552aa1bbaa319b2cc937f17aef4711862e944f2a9360c5d5a96c6baa7f40bee36ee65119c243e78a08eba11e48c109f652844af9837056635649169f2bb3d9dc209543907a6ae6d837f68d670bc7b0626b86b0ab7
InA = ad8ebc02b5c27c85c559292964696c2e3fd406142102d74d8ae9168131abea968da1715a08c67bed550789ccc9254e404045d18a89d4a4696996a5c5cd3c87cfc3d6e92985973d6cce02ac765bec09fdda16a4776c9d92c75431121d1bd453b8f296dac1a5538555823b20f2999cc416e62eaa90a3a2788d877d03b69e399dd089c7778e4d70d831e48a9c371218478612a2ac8eae6c8278956b1aecb7874da681a14d5e5a95325400ec0341f5d58767d0a7798b56bd0882d35b1fee076529fa8a13d523a965093178959a169de1643611870f869069de2c1fd5cdc514dcf626d5da45e7a34c9ee648295890e01f222fd56089a99c6c1b9ca947da5ea7ca32c7a0faa26bcf6ec390ea439defe6a19daa689cc1a1467cfe75d9285931bbc42f2f21d802cea83fc1aa27500762242c6e624b396c499dda561aff040d6f265760ab4d38256352b682682f90c1f9aa1046838ceb916061a550370d3830c0317be41a8f8853406a8f86bda08f79b3e31f8c7746da1c62553ba706020ede82e632a9061de666a8b00bb10e5f44762a99e47ce09c68d080b931e5c34d4be3dd8a7b56cfd762f610c2a183293268258082873779f418d30c7f3517e192236ac6e208c994ec9acd82c52e85f4642c0626763484afe6160eec7f8e2fa317a1ad89ee65c7dbc18481fcc42a757f3d7b48a90cb211703f1ce112e4822057f385b497b0325d94594b66997e5dbf972b9a70b010da0363b79fad6841d4ba8513bcb728ae50e3bc7550630272a5e189715fc198b331de8931af19a0bbfc9e24947b97c0e2a751aca732389252ee53d1093bc175ec0035013ff2431e4fe3da60cc769c0bb515aed63601e824097e750c3587b0569b2897754676917c7e154aefb5f829b60e71c8beb534be1f39a0cf36520a727204339796bd24885dcae7c5e18ba40ea3c553e193a10f6255734a6bc6e171f9898969d8cac08721bea50ad906b4f8803c695e76c21a46b285a728d3f054bede0b1b72630a5eae82838714b26cf35fc0027fe685b1c7d4d422d606cd23bb68e3fa052b5504b243313892e4d1123dc6661a4bd899cf44584e975b14a8dd6bc4c6e1a7b0ba1ee7c6cef815e561abee2052462e6ce46c92b0bc1c717e0aabb1f09c21272df5f6ad650d0e0528f04c652a6a4b6ae784fabd51a3395622dc274d486c36b47d4be3dd454324e12fabed0f6761c9712d1ea6e9224653348202e4000013d4ea0300b6c9bf6a40ef32c1429c28a24a7b8d14b36a15c17896ea0ca047e7c6609177c2ead50053224a5ea12dfb23095b905fd88b422646e991d1049b9a358f88ba76ba3a24a4018594546c1bd5d4f5ab19daa88cc33f46c6194e3217b00b500290ca88c2200a3493ba935949a9cdab90c477b6717ea0df127097e73d4fb30e659b6722853d468261be609e085735fb15e075414cded0e0825ffaa99b0bcef49fded751d6ddd63d37a4f787b74094b356ffa3b5d920749990700a8c24ac573ac9e87d71d02fdf7362d830ac8080f7212a206754fa3bbd1ea21b5195d53ca67769ce53c4451020190b58c821aa5ab9909d69303419501ed9098fe11c048fa1c48d816334468370e5fc21a02b0bc94d158dbde43f9694f441da613252853c7f8010ca98720eaef82599dbf5a84b3a125eb42ee22af05a495077499d43ac084283d2813b6c0fc268e0b432d7ed59fa06187320ef49a7501aa648d1faa1b1a5e0ee2eca253629ba167a670d86587652fcca51482f704cfe71455a192bce7af801994885a34a3a5a063c79860cb0a846b75caf889ac9221e41d8828a783d9510d830a4a5ca7074ed5804e4d60f24eb90a609f07bbdda2df9f7fa5daddb1547582a6b5a41ed2350d0a4875dcc09c8f929e951f231626c3bb245f498c8899bfa9ea610522190b92ac091260e1489089bc244cd57c75b3813d35d84d48d120531ba07c9aefa76733a93c140a737223e7d58e57705425554b52be20ae22c4e69496e5364c906f78f3687c7f0840eaf70b233557bdea0f896b5ac60b9494fb370aeb69d2698f3aff06ebd85ca19fba82873a364b6671d887faf673586f551890b116bfb0541bb55da875cbcaa0751e05b73f20940a26036c1c2710283fe44bfa8b295528212a5b20b750e787465325adcc469189ec8200e866b6961ce8c8c985d18f6bca78540457bd3c12a4de82fca18dda3e6a1ea38336a0d9d5f52eb52e831afd7d7f23a2c06295cabd38bd558c30763669b89289c97d8dba5ac005fdc87534b32488eefeb5148262202db92989c543b2e82105159cda8f1948513b2a28b7fda1c78ae6c1269021a991b91a20ad698e3105cb58e2ecfab1a8d61a904e63244596acfc89f8b146d966915237bd0ad0e79e2cf029d8087d25056b94a699f6684cc83646257f4d033c7d3a6b565aae8626706a80fde6e595b7215dee1e689d7865f5b6b6fb5a3ac90d84584d15e862d2c0ea9ab60e642c76592e7dae26972dfe414e8e5873c6c6f504ec27f4a91b7b5c4aeb900e1b5e927ac57
InNoiseSP = c64beb7608609174039c0966eabff18173e661d90f131e87d7ae8150e5c34773303d482a1d83f58ef58037e0ccf1aee263b3a8e0a6f4716019c3b735a4e5b4cc111c0b34623a65929394a9357224214776813e93fc1a03586de232a7a8327ad2be35a6542eb9adf031dd2a829662c2923fc25588de898075e4bd2b30921ccbd0f13280263a689fd4fb107aa35883f8212c858ff08aaabb6b0259154a0c479f40aca2a06d6319dd7ee75d6fc048f5ad6425c966cf1c6afd97108164c8828dcaf86a96264e85123180d4d97e4a43d620d9325b359a1788db6c5ce4cd08252d4c0f9d491132cd217da62ddea308ac8e992cbecb7a66bbe0909abbaff2a96f925b79f6516ec5c78ed3da0154030cbdc7ebe50286540ba84c54bdeb2b98f2693d69d9de9434a18529071a0ff96784288fd43550233ebeef51fef54e115ff5994b87072e2583806773d33969c8eb3bdba29a9012464278236159b542bd30aa8c6718ca3320ab6534455dbba143b937b24cd702c8d4963854bd819f9dabcc000005fdada7bed44a94263843ad6c08f7c05c09829c72510bc432411eff258c7d783e1676fbc7757321c6d845fbcd7ae609516427588cb4935438b76a64ea41f5f92ba167a25737748af281bb2b3646659e10db4896a4865013126cf70ac85098a305627a102cb4fb4d9d044498019604ef082f21393b588d81dd1a97a5640e171dad9dac6ded9874e52ad1eaaff519be29a35dc6cb60b044f5caca27eb9c96842758f2500592fe1f408be9381afbd95b557b3022b9ab00e2060498a00f5332802522ce41c6918a3a177b088d321b082b09eee19acd1986b9cd4f0802f6ba146e6c3859d0af7fd3a51a1d6c680717e3b1cf6e9b42e2a3c9094140f90289594e40a196112793e53a7a749fba7539061aef4518db2c9c981ee249d12f205e9f241949e18171e81c26700694bb3bcc474949f504ed98fcc827cc8e9b628b56ede94c3cca63e75c32aa9b41a5526c0160818c9c18ab484d49e015facce589c340ebe41d6c4f9ad66353f5ba6182d838cbf554a8ad4bb41b7396362d9dda2530a1411c15ba4a61cd473d0269e0d76e9c5aa8b3902c169269220c0076d215b61424237bbe46cad136d6c0dd220d42ab265402698b1d821a52512dc7c6ab0162b402ff8ab1b33da922abc61840ac76aa3505136789e07d461a08715acd713eaf3f42f40c46f848da48d15cbc2adeb705b29c33ebd330f8384501845eada58c80654a2cea07a3d558e4e80d81b8f943840b73a3272479132a2557efa6566b0688996f0e44ea171a52582a5abbd49fc12d35536bcc137283457de9d53a87295568cd5e6338a7b5b3664c26d18c99024b6143a5bd657f96e2320869305498864e34e9c046e6968705bbf530ddc73bb954817a0161b3ca898046b7eb97270ee48fb348a34b39d14933e18a47df80362ed4fc0227848fa448d061a11d97b62123f2985133d15a59f3d4dc83cb19cca11000320324c4a4bb008c965a2344237418ad00a5f2dfb609d89f89998e7e9470031bf0b06197198bdfdac9498f528ca7f817318e569816caab2944414113e3f89a08200e4921dd3ab85b5782b569d610b41f7a61d6ee2406e3e8e06429bc3329765592f04fe1403fc0fff88eb28f6587b2b6b1e5cc8cf1d44983c70e4de001500cb71807a8ea9a00f9cae380c8087fe8ef6ab157d90ccf234b206cee3823c3f775365c972422d0597bd01ae9e1596bdfde7c53617bb3964904c4897fb8f07515b525f3558715498168f12081b698a91e7b9ab7b80bcd2f1998a92255a4af3d4a169e73d3d255f2ec392c1a671aabd8be28c21207c636b12e49da9bf1978aa74723be73ca9872222e0ad439f681946e484867565f8ca48656e8f618bfda386209d9046a1c886b9414bd11e93178d0cc1944d84b987882884ce8271b5532332980c0d5ca8c629b8b81f65f62aa5545dba61e215249a7f2457c06965004db62e31e1344a7fe3557105580e6c181a184079090b535a7e15b04c434277b896cc98c7e56d2a8492b4f25a91c211d4a0bb219fb087453ede72402a17386c1c96770821f6fd4dfb97ce84ffe1d15133b765c7f6fc4b83d85b54704cb3bbd4a3221e990d3cd521874894993487a6fa25463645b89b8aa5aea272c9e2e0e2e14f010080f2e4f6fc6b771a7e7c377e91ce8896105e1e990714dba41a925479aa37bef79a963969bc16ce49888b8513e209820e3116dc786c39b8f5a4861ed4482f45e3c481fae6b6ce4a0fb9dffc76dd0b3b5046bcbaea678821655c434055106cdb3d2a88830d91345837bad1ac5cb230af6995aea644cd87e38a60393d024122d1a8ded1de4cff1050e98040866dda4c89278d02aa6bf5c4e31f442505e07a2889189c45994c5ced0de41b58baf44f2a7fc34259909fbc2f8b93356bf362086ac2493ff40ab3652fd9a890aad5c6c77a20052d5398649056cfbac185018cdb0c7779ab5898ce65b5af261921668d3b6b9186f6692db8c4658f29dc3050d7115
InNoiseEP = 56580d3581e9b313853d989e7aa880543520dd4d79ba81873613024324416364673aa8eba9f6428ae800496d492547f1205d67af20d2c6bfa4029bcb560d421ac9ede485fc9ce525aa141fec013ad09b7b5ef14b24ce5761f2065850a6d9c7df2843d610a00b98e52ba54cffbaf24c0596609c3314d1823891ada417b425612df3ba99e287f65cb7e1727cb510c92932bd35511dcf81f9b4bc81bde3a2b98d7e3d7a847c64172c7f1fd6a5d214ceaeb955581613b6a9d28743569bbd711920a768a0bc31be652460497cbc8dea2eb7e54d09045b0f89f36c0d111c83c7b46406fd9e15f3aec966bf6fe6836d4e1c0f41ea729358621c2ed3078b26936096f73a67964af5e77ba41be07238d6a062c6582d01ca41ca6e8a75079d1497119466550d25d06e84a979adcf30ccfebb158482baa111026ad314fbed709f4f21d0700a2e82ca94837a314891dd573e64d53a8bc49a0d796fa1b4c7c640b9739c7d53518d74adba7f6c1428353bb628f79d1ca195f4aacf97a242ecc6336e0bcc89a29d133c55d9778be105e4cbef773495342a425858ac2a6094dcf4eb78f139bd0cf0918246b8e89281b9bf5949c452dbb45a199dfda959c369b2bdfb2221aa0f5d7f4fef8087c6d04bd56f34b8f98297c31feb281cd0b0bed525f32552079e274395f3a16fec6dfb16fb7558be4169bbfda64131e8e93318f69d974f841964d4278f53e910e7f29287073eb7d939217dae13b10be11f4ad27dbb505198a9c2402bf3649b95c06e78bda95e504a6a91b6ee77d7ef3a51d07552d692a920df1a5450a67839c39a8a636b89b14b6d7d8b6685343ad2539856bbd50a24b0134f56d5b6c28069efe7089d2085a799e7232a4c4e1785d58aed5d489b6ec2c49ecc2b5069ea29acb82d3bd61b77dedc67cfa2b1964d8080e850f47bd4a9052d043eca734487d526c2453c6d3722a01810a9a20c73903d9a4e51663683b17a44952dbe00185584a19f8a85ba56a0dc6f6c2eb21407de982ea6c24bb4ba99941cdf846c2822e51d88d7b88a6005c642d607c67eed65b63466b050e2810a2777de0cc055f100c69c7219cafe07936618f54f981414394387ad95b1adeda3d94edf6a2e4db35cd0b463b17aa7a1973f5a225226a4ec2fe6ba4c504aed32cb4abd79374ae045fe6a4c7bdbc0aac0b8bda624dc6099de66aa007c4938e0b4995466f8c3fe7cfc051c64a33d8c8f15eb7520dc0c35dafab4fc8c595859f000bf44717c9be42448eca6da25e0b702eebf6b272f41dab06106093fb0bb8e27b584e6c86df28616df637820f905b623503bd14523948545290c616fb30213e7da511965a2c81576f4a0786474a3c508a68fa92168b8847c6e6755c8fa8c5c9368381104545667d1221ab59a13dd9dbef2b0ed36736e90515c2175e408956a9085a3950b7da321668b97525580013970f415bde3225534b82f2549e0dc339e117bb1d9815683593bb18d2c70d387be2a723097ca6e30ebd3322d18d85c1241aa1e361828b7cf8c229ca177103d8c1c028bcc84b80a1013af478198dea250cd20f86d46b6e95f52b8e2b40eade14c7974a563d6a85e86dc69396629d58aa7b6110d6da33a7b80555ba543e25c987754522dc96db560e24b72e9dbb260522cf1e6da744c5faf989bf14e128647457ad26622d3aae638dfd49fe69938421e8a9d9f1ea0c8720d7e6a9da7893c7440fd920edabe4d06419598e2cb2e59606dedc006bcaa2acbac9a2ecd3065697b92059c299aace3f02cd51675049f820b4a4e7480026bc71e19e388df193a0ab98be36a353198a7ae0ccbf928e67eb427137bf6ce25fbec0be741fc4912a22c68875d37f2ac823008393461a684b643c0b39ac0f6eb35b9a2ae0953cbe1163a93e7a104acb035cbc00ab86ba09b8bc1738766602579e15ac21f94686095d0c82b945330834f633b655e54984948f7dc6e79a67e52c195726e2fe6d518e2615c9a43a3aa2e69ac2e8c67f1615db3070f671a08a0d2250c755cdc9b97901e6b36f68d9ce34526330a17f98bb2a12c9d09aa4846c0affea228a6705b5115667c231acb86e62541876d51e2622840181d18d99d8a7dea535aba4e62a8d432280db67ecdc4c5b997c079c2214718d0dd7e5fabfdb4ab9815340c66c0fada45c6041e4bea112db4627ce4a08a5b3e42e9ea8c390ee84636807b4d4b4759958951fe3cf64608d7b7799a42600a934c75b85843e436cb4a70440025a5ab594128190ff96c1c82d555bdf543b82d3bd88fd078b4b2c51b6171c3e90587169938535c48c5dbea13b6b187341f2f61d835b99e4fe3799e5a3af787cfa68f2a100c6f38c120ad73f36d95da3de1184103b0f192d80cce06b3d36b20acd5dd116a1ac2b383aa4f37876e107a4dc01842e12d2d6b819a8139bd7b9214b3e7dc44039652bb8acdb12f0fff23f7ac445804281959ac1529d63cab2ab6170c220c6983da677348ef13c3840835d6b14361798f598cc2ca4b16ac76affe8017a63e6225ed4a5cd05b
InNoiseEPP = ffafff1b000c00008000f0fffebf00b0000000fcbf028000c0fffabffd2f011000fcbf0000002000f0bf00f001100000c0ffaf00e0ff0a00ff2f0100001000ff6fff1b00f8bf00b000d0fff2bf01c00130000400ff2f00f0fffebfff6f01000000c000000040000c000500ff1b0010000070011000ecbf0240ff2b000c00000000fcff0e0000000010000c00038000500000c00040001000e8bf00b0ff3b0004000040ff0b000b0001800010000400000001000000c0003001100000c00200001000000000f0ffdbff1600fdafff0b00040000c000f0ff02c000b000200000000080ff1b0008000340fffbff02c0ff6fffdbff0600ffefffdbff06000030ff2b00f8bf00c0ff0b00ecbf02c0006000f4bf01c0000000030001c000000004000480ffdbff020000f0002000f4bf014000f0ff020000f0ff3b000000fe6f0030000c000280ff0b000700fe6f0000000b000040ff1b00fcbf0180ff0b000700fd6f002000fcbf00c000a0fffebf0040fffbff0a00ff2f004c00f4bf01c0ff1b00e8bffc2fffdbff0600fe6f01f0ff0600ff6fff5b0000c0ffefff0b00f8bf00c000c0ff1a000100ff6b00fcbf0300005c00f8bffe2f00dcfffabf0040000000ecbf01c0fffbfffebf018000300008000280000000ffbffe6f00f0ff0200fcefff0b0000c00300004c00fcbf0180ffebff020000b000f0ff120002c00010000800ff6f000000030004c0ff2b0000000380ff4b0000c00030000000f0bf010000fcffeebf01800000000f00ff2f000c0000000030ff0b000f0000b0ffdbff120004c0ff1b00100003400010001000fe6f001000f4bf00b0000000fcbf058000b0fffabf003000b0ff1200028000f0ff160002800000000f000300000000ffbf014001c0fffabf0080003000fcbf0100ff1b0008000440ffebff1200ffefff5b00f0bf0400ff0b001300024000f0ff02c0040000dcfffebf0480ff0b000300feefffebff0a0001800030000400fe2f001c001400024000f0ff0a00028000000003c0024000e0ff02c0feefffebff2a00fdeffe1b000400000000d0fffebfff2f00fcff02c0014000000003c00380000000f4bf03c0ff3b000c00fe6f00e0ffeebf03c0001000080000b00010000400ff2f002c000000007000d0ff02c000b000e0ff02c0feaffffbff0600fd2fff2b000400feaf0000000f0000b0007000fcbf0200000c000b00040001200004000400000c00f8bffc2f002c000c00028000300000c0fe2f0130000c00fc2f0000000b000300005c00040002c0ff0b0004000030002000100000b0ffdbff06000200002c00f4bf04c0000000030002c000d0ff020002c000100000c000b0fe2b00000000300000000c0000f0ffcbff0e0004800020001c000180ff4b0000000100000c0000c0feeffe0b001300ff6f01000003c00480feebfff2bf050001200000c0ffaf00000003c0ffeffe5b00080005c0ffebff1600010000dcff02c0020000fcff0a000440ff2b000000fc6fff0b00f4bf03000030000400010000100000c004800000001700feefffebff020000c0ff0b001800feefffdbfff6bffe6f002000100000b000d0fff6bffe2f01300000c0028000d0ff0200014000100018000070ffcbfff2bf0140ff0b000f00ffaf00e0fffebf0080ffcbff02000030001000f8bf0040000000ffbf008000000000000240002000f0bffe2fff0b000300fd6f00000000c0064000000000c0fe6f012000fcbf03c0fffbfffebf0380001000fcbf0070fffbff02c0fe2f0000000c00fe6f00c0ff0a00fd2f0010000800fe6f000000ecbf010000f0ff0a0002c00030000c00fdaf00200018000780ff1b000400010000400000c0018000f0fffabf0030001c000c0000f0ff4b00ecbf0280002000f4bf00700050000c0000000000000700f72f006000f8bf008000f0ff020000f00010000c000040ff2b0000c001c0ff1b000000014001200004000240fffbff0a00024001f0ff0e00fe2f000000f8bf003000ecff1600008000f0ff1200ff2f002000fcbffe2f00d0ff020002000000000f0000300000000400ffef01200004000030003c0004000030015000f8bf05c000c0fffebf05c000f0ff0a00014000f0ff0a000400003000140000f0ff8b000400fcef00000004000030003c00040002c0ff0b00e8bf0100013000180004c0ff0b00100000000050000000fe6f01f0ff1a000540002000080001400100000b0002800010000000fd2f0020000c000000003c00f0bffe2f003c000c00ffafff3b00000000c0ff3b00000000400040000c000000000c00ffbf000001e0ff12000300016000f4bf038000100000000080ff6b000400024000e0ff0a00fdefff1b00f8bfff2f00d0ff02000100000000e4bf00400000000400fd2f00a0fff6bf00800030000400007001e0ff02c0000000000003000070ff5b000400feeffffbff0600fb2f002c000000003001e0fffabfff2f00f0ff0a000030003000100000b0008000fcbf
InRand = 13d4f1b473932b85d8bbbdbd30713aa4a25482ae0f02e3351794769e68e70eec
OutPK = 8b2d5c9aec7477f2e384b6a9ca064b029f6386ca3b760412859c647f78c364b158d8659c65d692b506bb4e56dc233189bdf703ed9134a47873cc14793f05aba55fc63ac34e9d02d3ef2a706e1a916a8816d8d07deacb2777e2b4a545e7e00575fd7a664b9d626bb05acda02a55e9a96afe54ecd6f95037edd2599089167b10e46d68f25258799ac46b166d9f9313d0e8f2d0a8a2a533b68ae1ac9c2c467071712f192bc809f2dc45b76e214a5d41222ec4b9d5a062a0b600beb70270aea1254cd8f79d4b034a357ba19527ea02bdd1a1ea09d04eabf568103cc4ca8be72e697a3e8ba131de02396c0a5b033742af982872ea3ade03f8a22059fad59fb21ee9529c544ccd9f7d64172c9d2515d6379b2e0df9903ec839e1b1db192a3a1ce5b1d94a17f748698a91cbf39306ad24e34ad329d3a8500cdf8bbbde0e2cc26b3d673e8a2159d0bbc0e5fd38f08e22063178b41a0d890b95761fec6bd5f64ebc260c6909008efa02f7477c199d32265e552f057606b13d84cab4de42094a94961226f58021cb1f34a95d1206a00ce286fea7c5aa40b1b93d9345ed1723b6747b1de69823ddb4409ba4391bbd24494011a4a590d20b151237a9e7a23b4be8865207514c666fec394406b367685880baa020eb5c6a556c614312aae258018d23b46f2c120cc43a8c9b082b755ab1fddd90b8eb4526eec8c43768255cac2c2d161a605ea90e2fa100a82448cbe04104e839ea617f93730064e0a963c3d9d60f4b214b29a1aa38380a5409e29878b788cad64db263449a69616d959bc8de606b40228dd38eef97797c80374b749a818a5ef40560a14701a4f4e45d1be415591ec47950aa9d6ca84af8986c9516a55be012a02d93a6a43604f9ed58a7dee509aab6576ed9a4217cd1bbf291864630723eb0d25c3ae7f123dbd12d92061a30de10a4e5a9dca35303e1379c0976295851f67e5237cae4e4566c8481382e2f212f580adfe4e18822d0a6bfd69a355eb670324e35559f95a9fe87222708d80a2b9269b075d660c020c2ba5c29acd809eacb71e266d627b7a322a9675203c4583e61a9b6c99ed6fd299e9992f60189be642d0b4bbb0e710153db50b4931c6849a4bc81608629a2ef850218f00d944be1ebe4f1520760c09119f47d751e85425eb89e309a45233fd290ae53f052074164b0cc35705f805b611aec389a209a122cb412d1d214f11314e427a931b5a82f49dcc4ac0ca5d347f49146bd6b35c62dac7689abd60be0399f045692484289491644ba9963510ef2c352a0e43c9589c6b52215c43ffde82ad868768c2da59727ffc45623eba8e3397995382471a60f4a82985987c110eab255cdf4319c88481e87f1fa80feac75eb0b626b71064d98a4c9324a7f9a58b023053c7849ee95ea7fe2510a8648b5894298d15776a49d35580122737a97968711ac9e98011c453b27f47b383e6ea46532678101374a2e6a8778e6b3f82212c240050a22cd40554aaea30b04eaf1b7748e7d51da4a1be83070eccab4c2f621fb93983b98940c9926b7d7f51a58ffa6d4a7350c0879546c4025013f952d9c410ecd7532d30b393b9a2bebac155468f48add16b6ca79e887bd5c7e12fafc71fbdda1cbbb8196b56dd3f168ce5e15dce5f0400030582e716056f85c5b10c2c5f4bd20cc6f64e2ccf179ee5f7864164c642d6356e6a89c17c91a0312f24859324b7d01f419691e03b4c198859a6b6b355964fc839c26f101ca88719b004492eed28a9d9c956519c053e0acc0350c2c3c82d4a438ec40033390fde66f2ab7672a16f8d7ae841d641754bde0466fa84b6822dca7766c7468205c12679594812d190153e54784665052961cdfc3fb3510084f44ea8bc47d00d8c7a0683a4178ab5e8725196334488ea9927448fae93ac72a548648d481122f166c8cc902161fadbb2325c2c4d89c79196a8648c49504b7036037337d85788b156865e674f6deed11965102ffe2041a7d9a55ddd53fe368828f6540fe79a4c4a1762dee08cb39524f89c0eb0a2a9246df1f85c1318c259f6dd6ae4dbcf39e91c9e3ba23f809bfd69d81bd749ddcb2bef679bfc6c118853e9736c9b5c808b4b31d254b444cd98c5ba104e6d368007c67e541ff42489d962c5462b5aa325f73e5e34c19998be96a705c78bb47a678f1a57819a887c2f3d64a37e997790f060f91c8b2760348802b1f854731003d21ab8f907c91861cc962804cb80c5cc26dd5802572c1594ce16cc57df24063289c582510cf5ff810ec43c2e0701b2a080d891992372c1979dd8420223cf04cbc401233d1a42fe646f8b2f2c98cd49cb813ab08b729a44f314c35884582d920e564659cef80aa61387029822713c2e868765a2917d8060c0115f5b6df3147548812216fd152ef4520c64e6a89de4a88946f7592dfc9ea20c61c8c1aaff83391fa71e6ce5e06f67e47e702663b137c275f5904e0c21c3b080723b75b492dcd03fc768ea633011ab3d3c4987cc5d96a92c22250b41ccf15beb885cca27352b4d9af
OutRec = 00c0003000000002c00030000c0002c0003000000002000030000c000100002000040001400030000800008000200008000340002000080001800030000400004000300000000240003000000000c000300000000300001000040000000010000000004000000008000280000000040002000000000400024000200000000080002000080003c00000000800024000100004000080003000080002c00030000c0003800010000c0003c0001000080001c0002000040003c00030000c00010000300004000300001000000000800010000c000140003000080001400010000c0002000020000c0001400000000c00014000100004000100001000000003800010000000020000200004000380000000080003400000000000030000100000000140001000040000000010000400028000000008000100001000000001c0003000000001c0002000000002400020000c0001c0003000000001400020000c000080000000000000800030000800020000200004000240003000040003c0001000000002c00030000800000000200008000180002000000003c0003000040002800020000c00008000100000000200003000080000400020000c000380001000000001800010000c000180001000000000000000000c00000000200008000240003000080001400020000400010000300008000280001000000003000000000c0002000000000c0003c000000008000040001000080001c000000008000080002000000001c0003000040002c0001000040003000010000c0000c000000004000300002000080002c00020000c000200002000080000800000000c000180001000000003c000300000000340000000080000c00020000c000080001000040001c00010000c0000c0003000080003000030000c00034000000008000040000000000002800000000c0000000030000c0003c00000000c00018000100004000340002000040000c00000000c000000002000040003c00030000c0002c0002000040000c0003000040000c0000000040002c000200004000100003000080002c0001000080003400020000800014000300008000240002000000003800010000000038000000004000340001000000002000000000c000380001000080003000000000c0001c0003000040003400020000800028000000008000000003000080000800000000c000340002000080002800030000800020000200004000080000000040002000030000c000240003000040000c0001000040001400000000c0002c0003000000001c000000008000000001000080003800000000c00028000000008000100001000080000c00020000c0003c0003000000002000010000800020000300004000040001000080002c000300004000100001000040000c000200004000140003000080001c000200008000180000000040002c0002000040001c00020000c0002800010000000008000200004000100000000000002c000100004000340003000040001c0002000040003800000000000034000200008000140000000080001800000000c0000800010000c0000800020000c0000800010000c000340001000000002000000000800038000300008000040003000000003800030000800034000200008000180002000000002400000000c0002c0002000000001000030000800018000200000000200002000040000c0003000040002800020000c000080000000080000800010000c0001000010000c000200000000000001800000000c0001400010000c0003800000000800018000200000000100003000040000c0001000040002c0000000000001000010000c0001800000000c000300002000040003c00030000400020000000008000000000000000002c00030000c000200002000000001c000100000000240003000080000c00010000000028000100000000280003000080002c000100004000300000000040002800020000c00000000200004000100000000080001800030000400000000100004000240002000000000c0001000040001c0003000000002c0003000080001c0000000040003c00030000400034000200008000180000000040002800030000c0002800020000c0000800010000c00004000300000000380002000080001400020000800010000300004000200001000000002400030000c00008000200000000000000000000001800000000c0002c0002000040001c000200004000100002000000003c00030000c000380000000000000c00020000c0000800020000c0000400030000400038000100000000140001000040001c00020000800008000300004000080000000000003c0000000040003800020000c000040003000040002800030000c0001000010000c000100002000080002000030000c0003800020000c000340001000080002c0002000040002800030000400018000000008000000002000000000c00000000000
Key = d5492977f04342e5c73557bce8b5f5c5a6c2e2acba0c8addcb834e797642aba6
InNoiseS = a80b21a95b81047b96b9897ff01246dd9b46644d94e9eebb652d84bdd21a45815d7441a863e381121a78479f8a8b8ca9b3ecc170c8ac0630b1dfddba2f28a373471cd809001b36ea92e6291e26da1bbd469d526e734f45d78f2c6a840533b955fc36330f3dc865d5b7f9d6110b2b3d0eb92f34b9ae344ba06f04888b3202c111ad4749a2b923aa08528eb6a18a08719b06f4793b0dd2c958da1072628fb9a410bb7c5c2165806a718ba1ca0850c191230083928062776069b14562d513e843be94ad3e476b4c4239c1d52fbf900d2b00cd3725dd5111c238ba16a61314c59e706885aca57fc505fb9dfbe6ce6829bed6cc76e9e1b9af52805a737e4baf2f37ebde562ea01172fa29c27e4ed7244308aa253fe11481c90c9e762b11a880a6590d58ed1139f62ba60313f4afed1af24c4764d79c89fda62d06fcfc6258e88979f2559ca0612f845a5c3d6f6c5df309ac8701cdc21a648996f8d8ee97c8d894382b3994b3357afc5d06682e1095f25c1b59be76a316159cb623f04b494deb258f043f216eba710e6e9b0ee772432a45456602942a39f1912ad530b1d3d0b740e3f581cf368acd463a23d3960066d92de33b0a4a398ff673a719b52e15ac91b6a51aa8144826fd657bb517cb65e6e9782dd30a324022bbd7cd8995a5346b32970e0ae9be9aa79c91826b2c0e3c87c0030f72149ca9a77a53e946402e291097158db12aad04dd0c839aad8c220f207214cc87a07d057a81e37ba81956ab24554f657c124e10683af65fea15531d03f1190ebd0b0278089cbe01b019b194ae6ab8c9ef2c8b82e16ff1a4aad24060a62c5e89a3676d12fc1f1be3ee0e552c15808104919e64000a92d55800486af24632c4b02e631a5572d5751385aa95d4b5bbb71ebd56548a6f4a2cbcc33485803c90187b227ab2829e732b8ad15dddc3450317a966201f4ec3d70a3d04ec9a79a2c98ef2a3a693672ead1f0d20e42008726320f1ebfe162ba0c611b03a32a0c96260443ddeab0b04ff9381f14363a6a4e90b45a356907196cfb845c9e68c91d79d2e74510f5a2556605b0505142b0549416e3f8125c65afdad22a88620a05fe34a998a46ba57043488c2102e23da22f18e680be20702d326f8a86ae4bd36d4ed4e0f53fcd9d59c0cdf6a5cc80325730a513631991e420daa12b9f191af12c9b429298157754cb7ead1be85f8e826371954bb15946fa6620c8d63c235e37e7cad391829c258446522e30a60f0fa7a41c05eb0b2fc8faadad38ba6f66ec70fc62b2e9976a1d56bb2b4b26df54621f26b75af4f5030a668e211d58d36688e10a692c541648214a9e8037b86ec2009f2e6c5c0bb4c7e91db3123818441c8675d672c6e7cfde43d359d39280a974bc3e128407ca6e2883f21bc612777508f32202f2558b5b6224b6d4da3e83c9d3c582f7ab1bba82c904a1a75d6668ab0ef8893f4c24e305063e6d85471ced2d74a383451ab027613cdd094476538f9d03a55be9e4d0788099a3a4acebac42865ae436e55df2123a9425270cb113818640b614f8c487966904043d531b58c44b50571b1d45e04b56c4a0332a180f0006e3da108a08978159282670ea10b4e4e89155285bcd0a4d90827f845683b5fd708f0aa9541af9e304b2eb87c4b06f5d483789a621b5431384d7615cff8579ca2a44f157c6882ca6d15e213a9c8fd85015bf8d55cd21d274c442b66146d8dc456718599a68e8d57869e5a4ca4d00b17996c2bc483e476421205e6095594f5a8908ec8c6a28c118b9f2e7794c9920b928f4a5729ec983f2c5ae4846c91d50ddf2b90f6513949187900aa8ef828d4640012006dccfc7a225168165fb32b3a9d535de29310fa669aba94faf0c37d3a32463ec711a474e1cb20c15b36845ee4f6785d6d1a0eebc771d68d282ae2326933211fb91ea08b045113feef903bcaca3ffb6898f61815890b5a09cbe2413e5394f3d65a42250fae3930ddcd1d3d63bd26714640b8ae4cfaa3e57f0fc446ebc6e0822e6aeca4625252591568e1f80aa29a0679e65d9c6d19ea2f388c1a1a526db1f674f22ceba41412fa247b192eae509ff831be8fe55433a69570a7b3b24f1c8d5b443dcadd25a11f0cc432136c79bea5fb5a83de240c64d0717a7299ce499496e71e675c20428834445aa99db4124df4615865b68555c8ae0b021a824324a81ce0be995352b84490ad84413608c12dc2a00e4a53bfdbbb403a2847dde4616a38ed47cc8b04334cde0269ef0120fdfdaf795eec3b98924cce1a3924198e36dd6bc638faa01d76559942508e400c5f10573fb98187a562ca966dbe1b900043fcec5d826d17eb4a1e3790875d05baba956e6cb9d88b211bba112217d01ca67e83e3f6ae187e82e7c3398c127f894bedc489f15f6faad152f2364ebc8d63009e241d01c2db7bb9d6487de303a3915c4699c3e9857d8403671d2a774fe618d34b75560e78285f11938a343d8f5663a396c642b8dbe44aea56325af044979be3cd37b0e3b69436f45d5e95883a47e09d
InPK = 8b2d5c9aec7477f2e384b6a9ca064b029f6386ca3b760412859c647f78c364b158d8659c65d692b506bb4e56dc233189bdf703ed9134a47873cc14793f05aba55fc63ac34e9d02d3ef2a706e1a916a8816d8d07deacb2777e2b4a545e7e00575fd7a664b9d626bb05acda02a55e9a96afe54ecd6f95037edd2599089167b10e46d68f25258799ac46b166d9f9313d0e8f2d0a8a2a533b68ae1ac9c2c467071712f192bc809f2dc45b76e214a5d41222ec4b9d5a062a0b600beb70270aea1254cd8f79d4b034a357ba19527ea02bdd1a1ea09d04eabf568103cc4ca8be72e697a3e8ba131de02396c0a5b033742af982872ea3ade03f8a22059fad59fb21ee9529c544ccd9f7d64172c9d2515d6379b2e0df9903ec839e1b1db192a3a1ce5b1d94a17f748698a91cbf39306ad24e34ad329d3a8500cdf8bbbde0e2cc26b3d673e8a2159d0bbc0e5fd38f08e22063178b41a0d890b95761fec6bd5f64ebc260c6909008efa02f7477c199d32265e552f057606b13d84cab4de42094a94961226f58021cb1f34a95d1206a00ce286fea7c5aa40b1b93d9345ed1723b6747b1de69823ddb4409ba4391bbd24494011a4a590d20b151237a9e7a23b4be8865207514c666fec394406b367685880baa020eb5c6a556c614312aae258018d23b46f2c120cc43a8c9b082b755ab1fddd90b8eb4526eec8c43768255cac2c2d161a605ea90e2fa100a82448cbe04104e839ea617f93730064e0a963c3d9d60f4b214b29a1aa38380a5409e29878b788cad64db263449a69616d959bc8de606b40228dd38eef97797c80374b749a818a5ef40560a14701a4f4e45d1be415591ec47950aa9d6ca84af8986c9516a55be012a02d93a6a43604f9ed58a7dee509aab6576ed9a4217cd1bbf291864630723eb0d25c3ae7f123dbd12d92061a30de10a4e5a9dca35303e1379c0976295851f67e5237cae4e4566c8481382e2f212f580adfe4e18822d0a6bfd69a355eb670324e35559f95a9fe87222708d80a2b9269b075d660c020c2ba5c29acd809eacb71e266d627b7a322a9675203c4583e61a9b6c99ed6fd299e9992f60189be642d0b4bbb0e710153db50b4931c6849a4bc81608629a2ef850218f00d944be1ebe4f1520760c09119f47d751e85425eb89e309a45233fd290ae53f052074164b0cc35705f805b611aec389a209a122cb412d1d214f11314e427a931b5a82f49dcc4ac0ca5d347f49146bd6b35c62dac7689abd60be0399f045692484289491644ba9963510ef2c352a0e43c9589c6b52215c43ffde82ad868768c2da59727ffc45623eba8e3397995382471a60f4a82985987c110eab255cdf4319c88481e87f1fa80feac75eb0b626b71064d98a4c9324a7f9a58b023053c7849ee95ea7fe2510a8648b5894298d15776a49d35580122737a97968711ac9e98011c453b27f47b383e6ea46532678101374a2e6a8778e6b3f82212c240050a22cd40554aaea30b04eaf1b7748e7d51da4a1be83070eccab4c2f621fb93983b98940c9926b7d7f51a58ffa6d4a7350c0879546c4025013f952d9c410ecd7532d30b393b9a2bebac155468f48add16b6ca79e887bd5c7e12fafc71fbdda1cbbb8196b56dd3f168ce5e15dce5f0400030582e716056f85c5b10c2c5f4bd20cc6f64e2ccf179ee5f7864164c642d6356e6a89c17c91a0312f24859324b7d01f419691e03b4c198859a6b6b355964fc839c26f101ca88719b004492eed28a9d9c956519c053e0acc0350c2c3c82d4a438ec40033390fde66f2ab7672a16f8d7ae841d641754bde0466fa84b6822dca7766c7468205c12679594812d190153e54784665052961cdfc3fb3510084f44ea8bc47d00d8c7a0683a4178ab5e8725196334488ea9927448fae93ac72a548648d481122f166c8cc902161fadbb2325c2c4d89c79196a8648c49504b7036037337d85788b156865e674f6deed11965102ffe2041a7d9a55ddd53fe368828f6540fe79a4c4a1762dee08cb39524f89c0eb0a2a9246df1f85c1318c259f6dd6ae4dbcf39e91c9e3ba23f809bfd69d81bd749ddcb2bef679bfc6c118853e9736c9b5c808b4b31d254b444cd98c5ba104e6d368007c67e541ff42489d962c5462b5aa325f73e5e34c19998be96a705c78bb47a678f1a57819a887c2f3d64a37e997790f060f91c8b2760348802b1f854731003d21ab8f907c91861cc962804cb80c5cc26dd5802572c1594ce16cc57df24063289c582510cf5ff810ec43c2e0701b2a080d891992372c1979dd8420223cf04cbc401233d1a42fe646f8b2f2c98cd49cb813ab08b729a44f314c35884582d920e564659cef80aa61387029822713c2e868765a2917d8060c0115f5b6df3147548812216fd152ef4520c64e6a89de4a88946f7592dfc9ea20c61c8c1aaff83391fa71e6ce5e06f67e47e702663b137c275f5904e0c21c3b080723b75b492dcd03fc768ea633011ab3d3c4987cc5d96a92c22250b41ccf15beb885cca27352b4d9af
InRec = 00c0003000000002c00030000c0002c0003000000002000030000c000100002000040001400030000800008000200008000340002000080001800030000400004000300000000240003000000000c000300000000300001000040000000010000000004000000008000280000000040002000000000400024000200000000080002000080003c00000000800024000100004000080003000080002c00030000c0003800010000c0003c0001000080001c0002000040003c00030000c00010000300004000300001000000000800010000c000140003000080001400010000c0002000020000c0001400000000c00014000100004000100001000000003800010000000020000200004000380000000080003400000000000030000100000000140001000040000000010000400028000000008000100001000000001c0003000000001c0002000000002400020000c0001c0003000000001400020000c000080000000000000800030000800020000200004000240003000040003c0001000000002c00030000800000000200008000180002000000003c0003000040002800020000c00008000100000000200003000080000400020000c000380001000000001800010000c000180001000000000000000000c00000000200008000240003000080001400020000400010000300008000280001000000003000000000c0002000000000c0003c000000008000040001000080001c000000008000080002000000001c0003000040002c0001000040003000010000c0000c000000004000300002000080002c00020000c000200002000080000800000000c000180001000000003c000300000000340000000080000c00020000c000080001000040001c00010000c0000c0003000080003000030000c00034000000008000040000000000002800000000c0000000030000c0003c00000000c00018000100004000340002000040000c00000000c000000002000040003c00030000c0002c0002000040000c0003000040000c0000000040002c000200004000100003000080002c0001000080003400020000800014000300008000240002000000003800010000000038000000004000340001000000002000000000c000380001000080003000000000c0001c0003000040003400020000800028000000008000000003000080000800000000c000340002000080002800030000800020000200004000080000000040002000030000c000240003000040000c0001000040001400000000c0002c0003000000001c000000008000000001000080003800000000c00028000000008000100001000080000c00020000c0003c0003000000002000010000800020000300004000040001000080002c000300004000100001000040000c000200004000140003000080001c000200008000180000000040002c0002000040001c00020000c0002800010000000008000200004000100000000000002c000100004000340003000040001c0002000040003800000000000034000200008000140000000080001800000000c0000800010000c0000800020000c0000800010000c000340001000000002000000000800038000300008000040003000000003800030000800034000200008000180002000000002400000000c0002c0002000000001000030000800018000200000000200002000040000c0003000040002800020000c000080000000080000800010000c0001000010000c000200000000000001800000000c0001400010000c0003800000000800018000200000000100003000040000c0001000040002c0000000000001000010000c0001800000000c000300002000040003c00030000400020000000008000000000000000002c00030000c000200002000000001c000100000000240003000080000c00010000000028000100000000280003000080002c000100004000300000000040002800020000c00000000200004000100000000080001800030000400000000100004000240002000000000c0001000040001c0003000000002c0003000080001c0000000040003c00030000400034000200008000180000000040002800030000c0002800020000c0000800010000c00004000300000000380002000080001400020000800010000300004000200001000000002400030000c00008000200000000000000000000001800000000c0002c0002000040001c000200004000100002000000003c00030000c000380000000000000c00020000c0000800020000c0000400030000400038000100000000140001000040001c00020000800008000300004000080000000000003c0000000040003800020000c000040003000040002800030000c0001000010000c000100002000080002000030000c0003800020000c000340001000080002c0002000040002800030000400018000000008000000002000000000c00000000000
Key = d5492977f04342e5c73557bce8b5f5c5a6c2e2acba0c8addcb834e797642aba6
InRandA = 38cbf333053e5c9addf8537386b88da15212a3a81ae15340f63f194faf1e9f38addc51fbaa72470e210d2a97f8c3b988456389d8a0c6928cbaa2a752d3e2a12d23d2297ec417b003776169d5b5b1198ce1bc10206f9ecd915d680b71ab0f14a87560400c8927492278ce10d6e3470912ce1bb275cc098356dcd9a3eee19704825332c146bf7dea0e02b3ec22802fd706da3283bb2bb7aa58d17c09264bd8dba2776fa9ab08ceed27aed39091d4ca732cdb4880ad35b201d0ad8bacd61015d07fe1ad3c9b1865237a2f28afc16b19311d61b3ba2021a8cf1d733f61e3609986aa006ba6053d1023b1e5a0b797900cfa59a1d5b40ea466830170f5187a4cde089752f4467b9ed487ea85335b4f7b2a8400133867ada22db09d79d478d0c9a88977450154bf74201e020c2458b29ec3d25b94d0992e4f89cca758806aaadee52a592913358da200d006373458cda6dc399d2ee4c765771a6d7e69057345de1047611125a9a04df955e71b3a026a5d5dcda81035470227e5188090462e64a806b9d539c0a13eeb9635710d516a10219683c459cb397b467e0fee4bb4d4d060d001093b93297889499c3698428107aa58f76c012d0e95d046c2066b94211f005e22a3b5ce5968a8c47a3fa9ead41e925356820b85b12ca6d588525184ac72ed2de5aa24e2716e944dd20d3e22e0c10b163c007aba809f95c6e4a1e6ddf0f4515e1094ecf7426a747f1eaada64b6ed1df26ff3e474a1586a090247558e050d162e1583151cd9694cf650208d6d600663ddda518fd7438036064c925bf5a5398e4f18aa90193100ae980b3c2633f43da46f1cc8a19c4bbc6b4cc0c595aef60254cb96350e105100715b084c100a5553337d107cd78444b1865814968303aaf28ed9c2edd7effcb51ad73146bf4c8900a15ff60449a19566b8ca6b4a75a76432c397d81e2eabec411ac409118cfe53b25041d146a5f8e579bcd59978a5afce582a519331a325b4beee5b4361199bfac6362bc76506138ab9fb38b11e01d6b78a2266b2f00a329a84a1873bdf85fae39d29a714c0d891d9b31647d052cee828a902b268eb593aeac0c45a55cea69c429040c5a1763c0f52e394fea300108476968529c24cff510ce92b97a6d2620946bb3c8ffbb518da2bfeeb69e7cf41b1d39859b24824b3f792f8758fcd295f21c3d6e428281a42a740f67896454ce5d50d8e984c9e0309828d303bcb2117c31a10a6cc7917c8ba803c464d06a2ca146d6e9e666045b78dd385356be976bc0963528b7a4a42524942a63921245a7a089ef92aba50afdaa629ab470fab604ccc39869ec496ec2c2a102e1871a54c5378880f05c380304067392629d5a1f121674ae09870e082ff29a1269a22ee9316e889071f21199a36e522baa3bd43e81186d217b57a022045c98f2a6b9a32b9dc9ea276256900feab7ad036c53202297667fdb681e996cbaad03269a01bfafa74d00f6525f5534fd09800155f74cca1206ae6e6d0e058a0538c5d8480aeb1ef4c755b21222ec265de576316b63829ed37cca935e154f10580c05c1d8f51fae6d6643c43a9d546b07deb89afd9780c5e7adc0baa69383f6b235b11e87a3660531039e89e00496a9be8088609318e166a5d0272aa473617359840e79c95faf9cd9f08547780cfe594d1aff6352b7d6b1468148bff2c6c37d6660aeae9b482543337b6453f531e805b60526fdd59e5c1ccb83568d65db81c1dabf5afa573a7190cd42ca1e459c145a5430b61eab011e28f965befb658b8844ff7b056777bd80dd2097245120f8e5887750d386b28302a7279d700d3772eee28f3cb68e562328a3226437b55b9b2be81d1318f5413ef15de9a48fa50a344b6c51399afca6a82301cf6417213014a5a45bbcd90771ac2397e19e117d5a92d0b94c71965a001159feb9325b961ae725b0b14722aa3a906b6b076e9bea80d7af7c6211c28ee6a44bd4c2eb6cfa93a332489572968512818799687422122a59ed981f6a3bfcd928f9f0372bf64b4db4cd315597642d80c7683f85839fd57eaf80b1542f84383e04e313b91a6a8798a729e02a530a621b5912a1ccecbfe7da8e067a543526130e06537ca89a20399e775a2e34ea739eaf8e04180043f01d74a9a954a4a5b6b87cfd43fa4e1a9e36beca135e56c23f2756791cf1814d76537074575e18c09a5f68187c34d2223358f59c220b5229f69f948156e9f658d74d59292542ed226b8cd4e074ee6d0d0d1c64a6a9c1765e90c67f35bbbe342120d40826b174a2dbc4566309368500010d289e942d421bee3e7c5b90471ff8b9be754c168ccd5ef640e56bfb2d1628146dc0a752305f41316859ecd263052a90c149cf2003fdc791a1b4e555cdd163eec93346742b8199eb17ad1c66e342b991a1cf950225532e5ddfc8cb0e36d3b390d253a193b955a124e01606f51e14e20c0435a36924a2e79c5ddf12d126c73925a38c4f8109d09737459fc6826ef12653648a52665f80664b147ed544653d3ea09259b511be4c406
InNoiseS = e5c40729d83a968c6b2ae550c89b6623e77579f20c14a6c8cb4a623b25da3973ebcc3ee5c92a34345957fe5d10827aa05da022a399332066a2679d11e83e00ac2be799dd3eb7a6a4c787e0b59fee900013ac050b77cbda453cfd06f0de51694b12433fdc32e37b16a8e60d2bb02b82101415850212b676144ba4145ef47731af3419fc8e406be62485d7da056868435a8d1c6a52823fd4ff3db975998aba564e7274525407c318a604a4dc1360c6629f9d425963019f2c9d05901e38abfe87ee51e4ea7c8591ed84c2f991669d6454d9a1b3b88e41e9309e94ae8fa797a91e27fe08f09a2c5e826b44b1626bc88098a4280428c05ffd8129939d450bd912784ae55e13c7044bc593e9406c1ec0c262ca59f225f60a812217471d1fe6af221c98a43135f6f6696441f17b698d92702f811702ce6b292e852723d21f996675c77070427be30a70f8fc8decd69c94c19c88949ac9b528261a26a77016952a7e91a17ea81be4bc4f2175d8b44835472e1606d0059a2e4d86c236cd9c8f27dbe9fb71800b5c335862f62acd0bafa1aa6821d585f7e6b4a5718a6020d4c53244b99d80718a09621766b7c158ec90cb0dee4bd630a9264a49db854e3af0126b17359842956ccca27e498df495c220ab9968000c021a7386464f958f8691a66c671186a26e484f04e5b29112e409ca5f366091d69ab4492f52e8f6abc7e561394ae89ce050bb776b7c3cb3c334f9e5da9fd3af1de2c68a2109ec683976a24cc4255139854c4a482fb8555e926c41a96db8f62e62f4ae6783bb48622a8e2373c7b0252dc40d52b1713fc48b0058b1f65a0fcdb3b8d07c3febd7eed55021773a58e9017aa90934c55f5799d53ee4aef2a8cb2209c01fafba6151be916bfdf15862204c52adcb0da5231408ebca29c02029cfda60baaa5aa09da3f3719495fa8de6107a6d175b030d8b84fe4e5b4f17032f447a20695f349ce8124d868eb7f2dab6820e6f78115c53514ab631f6fdbf3dda71b1be890d12e5bab273a9312d2afe739b6d75c6cb6446c445aa0198eb862748b55de2054acdf0b54bcd323ac6f27f4de55e197f7517210142e179d81afc501a88661d89be6c7e6aabac160704a5b6c1a2b829d9ce7486418fb92cfa23bd1ca3872a0b67b5ce4c62caf1a495bc442c11cdc87c06563d1a73941ae907d46ab77059166dcd11d12221582bb49ae411debc6cf36a9ed3c68643f7c18af0cf107e7dcabbb221cc201023a6156bdabde7e9b12bb3c64e0f0fb92a87ba2c59dcb8a5d48d97fce343ca0e69210b1c4d01897141ec4627e3a7ce05f848c4c558e0af50c36c053b100df69532935f46293a29c5c8e24ca3ade25bb427712f80263b736a6403cdd4c47b284d22ba4575d066d202d498e86b6ec23dba8abe87f63e375b0b6f41601c68fa1717e67b654ca21bfb428a0ca7ff5d2f51447e05a56e550a6790657cc3b0c736922fbd21b491694a64a11f45108b605f06d8610686f2912f504ff07f313edae07930cf8a4e838b0606a402625c494205fdfa764a5a9416853548364b0cd84ede3d3ae49af22f4d01ab127d31264eb8ace5d2554e55290a2d8979aaf88a761582f5c92a19f49ee4f573d54a61a638703e7535eb465bb6fa3a3dc1ab5cc452d826ef6e818a65aa842f1b60c57a50354fdaf1518f4d94c088ba049a5d963105f2a8e0819da6192361240474c5cebb328cdd907a2e04b0bda41c720c23c808a0918e68fb83dfe12684a4bb471eba7a0d48e75847a44042220ab85b412048da1981306d52fc659f34876d16ae89ccba803080b9268a8597bd57f00dcf79012cbb0528f9830864a129a5495879d228ef86fbc5bb39ac450b196a97200a1829323781d64fe981fac57b5228719adff3ee5e72c29af5a18d3e9635574cb65b4086e92fbb1ba62d36a823139955d186f65d05b6bc3915e5061416f548837d532a453aa50eb26848121a3a33aa5604c678249c676c8ec973c558f2e8ef88fb105998550da3cffa09838974403e8610370b2937bae154f488bf31c816890c83b878cacc577f2a3bb256687025c17cd595614fd2e803d1fa2891634772badad84549a71a5ae83e3b9418f6f9f6ca6d4a67d9c30459554bee4ce413091e1ca092a507d9685fd259d5f0b991d0645dc6d48a1fdf8171aa8e4c210c6cef97360155acdbe19b55f000012120e221240964cdf57b09900791e02f5168ddb798e3bdb1056298ef04d00a1bde9653e073e8899530db2d30961a4a58d604ae055ab56e5a0dcb77403a41e51b5d0895c675900c9e253d1851e9d87eabf235056bade602f0952ca1c8dbd5cd4a59324d5dfbc309518b5769926a4c7863c51db8a4249c6fce71c92b9c086c217f987a38569d923b01f58c3c3682a5a796223f89c7262160226cd8ef3730ec71a43d4e3053b2f15b855e3934501a90bfc6bdd9c3d6003ce2d86076215ce2db3e31bdd2266c8693e020129d63576617d3c68127608b7566b4be9dab7576b4167fa0cf610180153207d5ff9413488a
InNoiseE = 4dc2a8f9bbe84e148d7f5389a5a28bd7162a43aa2e3e9415d944324e10c17885d0856af0495cd531401e6a970a82d439943b6ac520527c2afc2f3cbaf4d401178b9293111d76a14bb1407ad61e05284f6398020ed2db4ab42da6abeda9b9f631646ff2eb2300566814e225332580cc4c5068eb176509703d188e39354211a6944e125510006b972fd12f218efc8f231200c1062e91e2137931a125d2cb4b4e0d129a275cc766351d7961a589d0c254a19651073a456a80e6e59b28b00a5413eeb9e9e57bee93528388749cd2c08b89e5d1674a07e7247db53ea14b804413769be256ad01de518192c0310621a26bc3809313c6c877972eb9b9dfd91e27eb33468fcc99c14012f02ee67ee6479886fe208eb41b47d03d9d3ca3138cf08f2a8d9064a1c94e69ae5d8fcc5181bca3556bebe67c09ab47c7237532c03ebace244854b25160d455ab00b93bf3ae4822118c9c49aa42e149523a2c6badf8feed721ad8d6e56b26a0ae6836ca486e00a24c522a9544140701519b5cbc4392c72cf60b6c5e85d44ae4ec2077971640f98b361fd09e16252ff02dab937308995c8a9905674761b408a38c5fa6671583844bfcc5e0041088450940f37d5880999636a1fc8fba69264bc79482d7a4b2fa33467af8048924870e6e97d660b58d01b85d501f2566d5150aa74e8b7b0009a14449714d4e34de2fd7a87541033d1da5b7aba57081edc539837600239a870669f52c45de3585b0710f2a645d1807c1b9526df45445857f78018067f65d051a5fb96413e68792647b8a94664c5a2430f4b4e280898af079c1b95a456695d21ada7540af9490b109507d48b563bea1bd214988d7241a18af9f85901f4974b45afe7520ea31bf97c958bba2022012d755ce8cbb1701e7d730fd48396165309321bb2f5c45c9c8a153d22366849304277050dc31751d21db9fe6831c8506769eaa5a6bf4a1ab0adb72b5a003d75187d906e679b06dd63118a91b37a3748544c97eafd44fe5c90abec58acf93762471ed6b51a330082e624655d7846273aa9a78f667e47d4fef8c0981dd28896ad516288c85dc476493951a4cffdf8aa3ad706a4e6425b3870a5b27ce517afb1aa8808092bbd7161dea9048c9015ab10956f4c0b9e88b6c86325b5e6571df5d3c382dd94acc55ea65caf452bd1e3188c694b66924e793ccac23625cc7033cc2a05991d8bbc71e5c7c851871e2da8af241e198c3285946ad1603dc7990ac0f436a1bf2a8ee009c53c8e51eff9b3fe69ec4a5bc661a98a82074bf41df22362a32aa5318a800563bf40b413740dc1e3c0b20f160d804bb147ec55f5e09c8c834b78a8120e80c95aa84de5c0459f702257c6ccfdbfcb7a996970a0a3ed0e72ea11e09006a47a8424a494b383602ad9daad233befaa70598d717d52cb7e44be1b3ee4e948727cf071a8cb05e54a766f54e7935aaef25138db4d4468d627f9a090a689a7329718de61efa323645850685ac742e0e7c725ad006fb4a7209d2d1b7845e344b2ad9c29bf979bdea397a8d3097474a20c2fbea8071665942536a6e1f2c3bd7b54400259b3210147610c12047d705cc700e1f2d7879fd63fe69c554b64e02c76a4a1ba4c23b7f4e6fb000ce894598f27049f9ba0c257d5160e27b214ae151da0479f1069df0f4814b4b8636d84c0c963d2887a41cc867209c9fb219bc9847c10277f80d32ae40f88060f651739c77689f3640f1eba789a254b0cd191b61c82a48afaaeca4194031e8417cc0144d63c4643616dd2215a980236a02c60f8e67d7a42104949d4a1ee8d38cb88cc7a6b5674904984a894966e673578105ab3274bc3b015ea992bc6a70994e845669858b0062c0d1fa6defeb64c3d3e0a8a49e4de6892980c85a901295a479475438fa59b103dd1bd083d79c193a89db61d18c7d2d8410d5b63d3c04a85464713e8a856abb17aa1c935e5e2c791b0d5b2899bb2088127fe8907b7390f1bda841f48632561bbc2ddda6f2d01fac069629f63e1ef0821b388bf86966e178d82b3e9776a47bc011091c5e02dc12617c681be877584129617781a1d2a8b8a905e124a63620ad74cee68bc0d1a0cb4bda493f353c93200c533bfc6c94800e88895e045e09f6d4faf662468143955858768150746aed404d3e81a1f34ef9083761b1393b008ad524a789cf5da8862cb66b70a800f7a84e7aaef13456483d4ab8e8045659615237e6183f4be799583822b84bd397e7cc9af9865b70443679f52638910e7d3ff5c7497af2054e31927032e47d9b3a5fbae4613853061fecf8cc3d46a04aae5277021b0f2a4ca2cb6027b66d8d17d8089780a39794126d75744b7294775ca0675e3a32f7b62ff0ea6b033c0e3f77e39bea7e58b86ea0b973923295a7262b71657973f69133470da2565f4c4f3b24ec9bd5c309eab95db467a355e8cd385fd79fb766cd9d97a182438a56e11b08a3a57bf1aaad1a465d3557ba552a0168d4744d6020020b312eed92496e5a4502650c1529b5d549b98f59dd7831033e41
OutPK = 41aa3310e40a5c72e000a825b951fb43b8145b3d240dc83aa705fd81a585a0b20894b09bc641244008319d5674e3dc916955877d153c3d9c04236e5513c67d535c704922ea0af16cb02423e0a8831104f6533c98264fce6a59d055ddc55e15a986667cc8c46397e6831850ed94d3416c320ea1502570936b9ae649d3c22a6fe104c30c15a6a915c6416ed891016435c8db948cf796a99189fa8c1601d1ca03b93bf80bd47591342c6dd9d976c77ea631e2b0d15eb569f2d9cee48d4a4e7de8c17a5f8046dc83f83916fd6ced61cbb6a2058ff22e685465e5ba97cab0312f5669d458f7d596f2171582afea02549766d1aa09aa39054080b174574875ad0579da369079565ba413a360198f92f1fb0a3d3ba467c3c5f1218bb6a9cb94373e1e0d0bddd53d24bd05c101db21b2b41a8b20822829bbfbdd3a93821c6facc547152f71771492a0c2c709aa541b5fb0a43a50d9ac5fa414509d09d448f4f271620c1159026768bc46ea9364e906571fab6976105d34ae22cf895fcc087461706936ee0a0ea4a8f9b73039cf18b874a7582ac3af68855e1e9d8928256158b801ca93178a16ac0f61c6d0234549abfe1dcbb9386084295d43a4324ca3015f575235285e6a97a125fb088706dd0bb7922194631cb0b46fb11e66c5a2f753aa3812d74c62519230019f6f27759dad24ee2365d3ec13809c920abe9c587f817d265e1d1c551fb917e85d53ded3e530afd648f72076aa0f396d41d824dbd46a79ed2e276b0025bc49e4b738cd166ee9134b1366558ed3a3f838b6c55f2bceaa6b6a55ac181d591a5c3d69cd4be59a7ea68de6e00ae238ee37475c0221c2f0785fa3deaad4eda01505480a171095206794330a004c37e9c0a9af38936bab9bcaaef2496eeac863f392295eeb6fd793f681c39a3b255f4e91228ad9d6831039da8b9948da25b830102b8468be17a5a317732bae56f407a575e8448084516202435c22d42b1e08e8b127498f3f50b99e08719e4595ebde9b54a76d7b8e145ec48002623580be54e99c4696bd4c47d28f96079596311f7ee7951513040a9449f2a806a04f20e4d5f25a23c84f40262ab0f144ee2956b66c7c8e2c38ff0c0a29df461080cea94c470f90ed1635340949280ab15e9189e9f054e5a39797a291c724162f64df6a4ad93b3a4f80845411124fdfd61320a4176c04cde3011a770add6870e36c0b8594083ad7d1246a22ba1611f88290138d79f6249fde82a920fe95a0c3d1ac017ebe55205eef41a8c01f5813c05a70c11908a37546e4101af12342c70cd05d03a1ec5404ada42a2d29a9fc8811805e5490a0317e1667dacb21a9a1d2489816cf1e2deaa2c708b5b03216cf2350546c062bc6e6e81b52a851826e9aef2e4ed55d18e99f8401c5db7709f659b808007c847e90754cdd7c55d850b0fb5077fb606867e3e00b9b109552a61cb187c6416e0729a5294f4e6ebf892be54ece31c74507237edc5884987237d5c270f52a86c429781648188479268e9e7eea00d12f6e321857d7948d388de52dc5d52d46b606848ac970c8ad49610ee8785470f71a10cbe3e48bdc497e5123890e1a93586089cd917a14fea4e4de89c885db8bafd2615a6855e1ca1a303443af75ef9d1239c3465bc9e0b2880b89b0d0140e11c147e894fa1096e75c4b863e69ef2f2c45c4087d40dd64130b58739e445bdb141a7f39d7d9a2032da8bbecca12d5aa1a718040834fec212f139d8aa4f50ee5159ff5102c2dad585ce19c8972b215f761e87d71d45174c4486a2c43a4435400b986cf8727c2e2009127405e39b85e1cea1e9841912567200bc6e5b2fc52ac0b895043228292adab063ba81ed049f5e1e0749d3e025ad16459b4ca18db00ce61a164d9d352043a6f44e8e7949c393a0aa56fa0bf8d065e531cf570a09e1f21b6c7ee507d6e803999296576bd243f3410e42adbab7e19a3098ad75967c248dc0359cc68a5d6ac1c6c81fdc1c1f6a00f530aa2facc51b0ab9cf8f408afdd2967dacb586b721a54f7363d87f1af0ed354d017b567ae0b2440279f4c5e237360018194a8e38bba66316d7634f1002d5d245e5019ad08090a35b732e84aae82ef9bb329286661f9e5218da95a6deb6ab7416b551361444ed890866a8cbb70ea59b20c05a64fbc94efed92f72faca2584d779476d41c5427d9119ebd6d94af6ef9306637cc4590f705dc5f28007568c7748d49248483cca2accc1a6bf008668878c853a1d09c247e0c3854dbf55647ae9ba2194c4a111c99e032f830b69b9ef8c45a864c23876343ee870290ff33b8241a4a95808a0fd17217af5803d5f83e676d29914290ad98addc43f77a85fa6623b0a254af2a87ae677c18029049a225681da84ccd9d37ddd50b8a205c7b9f2e140256d278c4c858ffc9fcb5d7c2aa302abeb15c6c227f5a4508dd0579164264fb953487f5a077d9a4ed2fac17dfe22012a327ae89a1e6b99133ef6415ef953056117f9b476d58d6865f577d65576559a03660a912789870fbd42520
InPK = 41aa3310e40a5c72e000a825b951fb43b8145b3d240dc83aa705fd81a585a0b20894b09bc641244008319d5674e3dc916955877d153c3d9c04236e5513c67d535c704922ea0af16cb02423e0a8831104f6533c98264fce6a59d055ddc55e15a986667cc8c46397e6831850ed94d3416c320ea1502570936b9ae649d3c22a6fe104c30c15a6a915c6416ed891016435c8db948cf796a99189fa8c1601d1ca03b93bf80bd47591342c6dd9d976c77ea631e2b0d15eb569f2d9cee48d4a4e7de8c17a5f8046dc83f83916fd6ced61cbb6a2058ff22e685465e5ba97cab0312f5669d458f7d596f2171582afea02549766d1aa09aa39054080b174574875ad0579da369079565ba413a360198f92f1fb0a3d3ba467c3c5f1218bb6a9cb94373e1e0d0bddd53d24bd05c101db21b2b41a8b20822829bbfbdd3a93821c6facc547152f71771492a0c2c709aa541b5fb0a43a50d9ac5fa414509d09d448f4f271620c1159026768bc46ea9364e906571fab6976105d34ae22cf895fcc087461706936ee0a0ea4a8f9b73039cf18b874a7582ac3af68855e1e9d8928256158b801ca93178a16ac0f61c6d0234549abfe1dcbb9386084295d43a4324ca3015f575235285e6a97a125fb088706dd0bb7922194631cb0b46fb11e66c5a2f753aa3812d74c62519230019f6f27759dad24ee2365d3ec13809c920abe9c587f817d265e1d1c551fb917e85d53ded3e530afd648f72076aa0f396d41d824dbd46a79ed2e276b0025bc49e4b738cd166ee9134b1366558ed3a3f838b6c55f2bceaa6b6a55ac181d591a5c3d69cd4be59a7ea68de6e00ae238ee37475c0221c2f0785fa3deaad4eda01505480a171095206794330a004c37e9c0a9af38936bab9bcaaef2496eeac863f392295eeb6fd793f681c39a3b255f4e91228ad9d6831039da8b9948da25b830102b8468be17a5a317732bae56f407a575e8448084516202435c22d42b1e08e8b127498f3f50b99e08719e4595ebde9b54a76d7b8e145ec48002623580be54e99c4696bd4c47d28f96079596311f7ee7951513040a9449f2a806a04f20e4d5f25a23c84f40262ab0f144ee2956b66c7c8e2c38ff0c0a29df461080cea94c470f90ed1635340949280ab15e9189e9f054e5a39797a291c724162f64df6a4ad93b3a4f80845411124fdfd61320a4176c04cde3011a770add6870e36c0b8594083ad7d1246a22ba1611f88290138d79f6249fde82a920fe95a0c3d1ac017ebe55205eef41a8c01f5813c05a70c11908a37546e4101af12342c70cd05d03a1ec5404ada42a2d29a9fc8811805e5490a0317e1667dacb21a9a1d2489816cf1e2deaa2c708b5b03216cf2350546c062bc6e6e81b52a851826e9aef2e4ed55d18e99f8401c5db7709f659b808007c847e90754cdd7c55d850b0fb5077fb606867e3e00b9b109552a61cb187c6416e0729a5294f4e6ebf892be54ece31c74507237edc5884987237d5c270f52a86c429781648188479268e9e7eea00d12f6e321857d7948d388de52dc5d52d46b606848ac970c8ad49610ee8785470f71a10cbe3e48bdc497e5123890e1a93586089cd917a14fea4e4de89c885db8bafd2615a6855e1ca1a303443af75ef9d1239c3465bc9e0b2880b89b0d0140e11c147e894fa1096e75c4b863e69ef2f2c45c4087d40dd64130b58739e445bdb141a7f39d7d9a2032da8bbecca12d5aa1a718040834fec212f139d8aa4f50ee5159ff5102c2dad585ce19c8972b215f761e87d71d45174c4486a2c43a4435400b986cf8727c2e2009127405e39b85e1cea1e9841912567200bc6e5b2fc52ac0b895043228292adab063ba81ed049f5e1e0749d3e025ad16459b4ca18db00ce61a164d9d352043a6f44e8e7949c393a0aa56fa0bf8d065e531cf570a09e1f21b6c7ee507d6e803999296576bd243f3410e42adbab7e19a3098ad75967c248dc0359cc68a5d6ac1c6c81fdc1c1f6a00f530aa2facc51b0ab9cf8f408afdd2967dacb586b721a54f7363d87f1af0ed354d017b567ae0b2440279f4c5e237360018194a8e38bba66316d7634f1002d5d245e5019ad08090a35b732e84aae82ef9bb329286661f9e5218da95a6deb6ab7416b551361444ed890866a8cbb70ea59b20c05a64fbc94efed92f72faca2584d779476d41c5427d9119ebd6d94af6ef9306637cc4590f705dc5f28007568c7748d49248483cca2accc1a6bf008668878c853a1d09c247e0c3854dbf55647ae9ba2194c4a111c99e032f830b69b9ef8c45a864c23876343ee870290ff33b8241a4a95808a0fd17217af5803d5f83e676d29914290ad98addc43f77a85fa6623b0a254af2a87ae677c18029049a225681da84ccd9d37ddd50b8a205c7b9f2e140256d278c4c858ffc9fcb5d7c2aa302abeb15c6c227f5a4508dd0579164264fb953487f5a077d9a4ed2fac17dfe22012a327ae89a1e6b99133ef6415ef953056117f9b476d58d6865f577d65576559a03660a912789870fbd42520
InA = 38cbf333053e5c9addf8537386b88da15212a3a81ae15340f63f194faf1e9f38addc51fbaa72470e210d2a97f8c3b988456389d8a0c6928cbaa2a752d3e2a12d23d2297ec417b003776169d5b5b1198ce1bc10206f9ecd915d680b71ab0f14a87560400c8927492278ce10d6e3470912ce1bb275cc098356dcd9a3eee19704825332c146bf7dea0e02b3ec22802fd706da3283bb2bb7aa58d17c09264bd8dba2776fa9ab08ceed27aed39091d4ca732cdb4880ad35b201d0ad8bacd61015d07fe1ad3c9b1865237a2f28afc16b19311d61b3ba2021a8cf1d733f61e3609986aa006ba6053d1023b1e5a0b797900cfa59a1d5b40ea466830170f5187a4cde089752f4467b9ed487ea85335b4f7b2a8400133867ada22db09d79d478d0c9a88977450154bf74201e020c2458b29ec3d25b94d0992e4f89cca758806aaadee52a592913358da200d006373458cda6dc399d2ee4c765771a6d7e69057345de1047611125a9a04df955e71b3a026a5d5dcda81035470227e5188090462e64a806b9d539c0a13eeb9635710d516a10219683c459cb397b467e0fee4bb4d4d060d001093b93297889499c3698428107aa58f76c012d0e95d046c2066b94211f005e22a3b5ce5968a8c47a3fa9ead41e925356820b85b12ca6d588525184ac72ed2de5aa24e2716e944dd20d3e22e0c10b163c007aba809f95c6e4a1e6ddf0f4515e1094ecf7426a747f1eaada64b6ed1df26ff3e474a1586a090247558e050d162e1583151cd9694cf650208d6d600663ddda518fd7438036064c925bf5a5398e4f18aa90193100ae980b3c2633f43da46f1cc8a19c4bbc6b4cc0c595aef60254cb96350e105100715b084c100a5553337d107cd78444b1865814968303aaf28ed9c2edd7effcb51ad73146bf4c8900a15ff60449a19566b8ca6b4a75a76432c397d81e2eabec411ac409118cfe53b25041d146a5f8e579bcd59978a5afce582a519331a325b4beee5b4361199bfac6362bc76506138ab9fb38b11e01d6b78a2266b2f00a329a84a1873bdf85fae39d29a714c0d891d9b31647d052cee828a902b268eb593aeac0c45a55cea69c429040c5a1763c0f52e394fea300108476968529c24cff510ce92b97a6d2620946bb3c8ffbb518da2bfeeb69e7cf41b1d39859b24824b3f792f8758fcd295f21c3d6e428281a42a740f67896454ce5d50d8e984c9e0309828d303bcb2117c31a10a6cc7917c8ba803c464d06a2ca146d6e9e666045b78dd385356be976bc0963528b7a4a42524942a63921245a7a089ef92aba50afdaa629ab470fab604ccc39869ec496ec2c2a102e1871a54c5378880f05c380304067392629d5a1f121674ae09870e082ff29a1269a22ee9316e889071f21199a36e522baa3bd43e81186d217b57a022045c98f2a6b9a32b9dc9ea276256900feab7ad036c53202297667fdb681e996cbaad03269a01bfafa74d00f6525f5534fd09800155f74cca1206ae6e6d0e058a0538c5d8480aeb1ef4c755b21222ec265de576316b63829ed37cca935e154f10580c05c1d8f51fae6d6643c43a9d546b07deb89afd9780c5e7adc0baa69383f6b235b11e87a3660531039e89e00496a9be8088609318e166a5d0272aa473617359840e79c95faf9cd9f08547780cfe594d1aff6352b7d6b1468148bff2c6c37d6660aeae9b482543337b6453f531e805b60526fdd59e5c1ccb83568d65db81c1dabf5afa573a7190cd42ca1e459c145a5430b61eab011e28f965befb658b8844ff7b056777bd80dd2097245120f8e5887750d386b28302a7279d700d3772eee28f3cb68e562328a3226437b55b9b2be81d1318f5413ef15de9a48fa50a344b6c51399afca6a82301cf6417213014a5a45bbcd90771ac2397e19e117d5a92d0b94c71965a001159feb9325b961ae725b0b14722aa3a906b6b076e9bea80d7af7c6211c28ee6a44bd4c2eb6cfa93a332489572968512818799687422122a59ed981f6a3bfcd928f9f0372bf64b4db4cd315597642d80c7683f85839fd57eaf80b1542f84383e04e313b91a6a8798a729e02a530a621b5912a1ccecbfe7da8e067a543526130e06537ca89a20399e775a2e34ea739eaf8e04180043f01d74a9a954a4a5b6b87cfd43fa4e1a9e36beca135e56c23f2756791cf1814d76537074575e18c09a5f68187c34d2223358f59c220b5229f69f948156e9f658d74d59292542ed226b8cd4e074ee6d0d0d1c64a6a9c1765e90c67f35bbbe342120d40826b174a2dbc4566309368500010d289e942d421bee3e7c5b90471ff8b9be754c168ccd5ef640e56bfb2d1628146dc0a752305f41316859ecd263052a90c149cf2003fdc791a1b4e555cdd163eec93346742b8199eb17ad1c66e342b991a1cf950225532e5ddfc8cb0e36d3b390d253a193b955a124e01606f51e14e20c0435a36924a2e79c5ddf12d126c73925a38c4f8109d09737459fc6826ef12653648a52665f80664b147ed544653d3ea09259b511be4c406
InNoiseSP = b1854163d7624f012383189759bdcd5ccb464ded5d1cd229a2c4fd610eeb3a568e2900ed165616cea24d09853c0ab8658ced40e7751bf1b34ae4c9896ab621992aef37b9041446a9a3495cd942ff266a04c5b9039b5f18420f51b976a1b4d9a81095f00d4cb4e87144284df1a470c25637ed724b21da34206369bb7a5624e341449421da69a3464451c53c3893919533443594761c30da94ec8295807b78e8ac8e80d05e745375a37f9027691b2a309e85d255bf7c06178ac212b90d1c3d262d9bf6096c5d806e39ada889afd21db68d6192a318a2fb09288c6180c7c4843129e0eb9db966aa317d127d4318f9a677e95294283452f8612635294a9fa31cb08bca6d4dc0a3e2239c753301080c4a142d08502fe898b288bd6c4230046c103103aa3cf84a65860951a0fbb990394aa03035b6d49342a57a86cf687860ae0f70544aa6f2020ee558e5911161b793d1764fc55aa2098de4bd9a6749ebf2298c9941de469b94891004ae06d944a7902f02093b404b684f5c6bb0b000bb608ff2b7a904f7a266aba00d04e30fb915d40893d411b91a0785a037477f344aa02a57e81ef7b88d49f6c0b589af5152cd16492b5c16a3cf4da893452ea4986347b22cbe8ef48945026ef68f822af9f6e18ca0fe403e12a1ba187412f2e6c4e59f2f0ece65fc4d45ecc7f47a058a5a55e503cb5a485e23573de071388365a81e76f98eb6ec4203f346e0b670d29464974249045239e119f545ed6a6f57c5e80ab15266c2a87d15418ab3588c218477ceb65679020f0a96d9c74be12fc064b999f5ce7a24e36d89b6714d3dd52af3145849689dadf603f2bd7ba3e3127a4c03ff2a90f7f1cc1a4388a05a1b6098a6236b32069c0f5baeb8b2be20125d80e9f3576c5b114968e1d9c43159a281a9c70c87291f6646f3e2a28796898132218890a62cd799fd1bb14b979a0758665c11b7a690dd05dd2e59b68eaaa98ee1fdc6aa111fdd2a11fa1150b99b10ad47ecdd6b2481dd63704c56cfad7ce0e7bc64ea169bf25f799a279bb12969683fe493069b7422bcefa49b12c964700a66dda50e525ba04d4f0be93aabb7e0b1335888a5de0e9c431c4592fb6d2384322c26f005a7a3134ebd48a5b299a94d6d7ae4d37438d55f69101b457a7198cbded8ba2f5d85360b70fb1476bc80281c77f4cc5b9521aa52e01443f09e30a0929a8aa804e9f0f5b52b1fa0c805d604989ed3d9cbb1c66ea8a7e160e9b01d0d642ecae2b91548023e41125e5b96ddccf5f35a89b4c0c79a7259614921b9862b6a91674d49a8353c63f89ad3eae1ea5040d176e28632209f5dd2d37182035d0b34b2d2fd49ab1b3885d55180691ca7c93bca936dd9f7b71c741b7eabcd71eba93b6cc8ed29de343e00a6a7a74ee6913b160bfb8ea4897fa97e2b8f2d27456bf945c121b29ce9e8c4749d14161f65d2dd3db0ca1f2f853975191e48aae5b7e684fc5ab599ed11b83b61cebba59e4ffec46830ea1cb11e2b5075f0ee4b58538048c62241f2d73baa39fc8223268f818660bb9b96fbd42ea50f7e0199760ff07254e913530a112f7c2b35a7177aae3c9f60d8a62238979d2d81988d084045abf10790beba42ee8b07a006098bdb42cac11dea20f5e2981880dadf42f59bce784f130da97c645c2f661b8167f1435ad8eea3e004459e0d5628bca93a390a530b70148fb51ca130dac87f96559146d66010d54820f525d469622cf13a5a8a79f09a1088178e39e794ec756ee15a351651f6fbcc4cb786f6d60e1a53cdc5251631f84e6d6cdbc9e9dd41165e4872f6ee35c0d8b6db7dc48d6384a9287f65461044d08be3c29f2708a57496fe966a659db13d496ce16c39c34aad76ab80a330726078a0a8f9429ddd7e9c91c2b3b1594044a658e3f46e3a079a98222a9a5074883095a6717ab807a4b2b77a4894c5c6e0dfae62abeaaed26ece6b29553413df7448fc4e40b7311e3bb556716ab2c921d36b1ee7e65111c6224c300e466a259309c39de94a7d5a32764c4259add929900845829c91a677fd39355e2d3392d0c547875a43f05f3819c1ed74a86a890cbfa8255645916b62a1dbeaaa5d94e80f54d831240ed266e07bafa0780f92fbb147109e2a65ba6536d01154cee3e577ae2afb8a3a761d9169b5afcd322f85558bd0a762be2821a1290af2c50c194a2a7a85aaaa1d68c11642de8a3c1a22674481782f8847b8330ee4091a281e9bd3e4a5925bcf54f062bc4aa20780497200e61e4bd537e0515fda23246c04943d0d3b59205c501610118ac73c2f33e5b15b3c49123e9e1be9b6b8984b13146497b53b48574b85c376565c5cf8e82d0049f3d591e652947fa027b011fd008042ae6cdb7c6e3e55833ba0b0a00cc1248405b9d90a17cbd022fcb049c0cb6f0516c2a566eb776be7194df155e3ba46f10ec3272f879dc1186d2b8851b938119656c563b95d7977eefb73a1929991c0f413b99049269597796688020ca0a6e401263ab5691934a3d971aac2ce626b811c7c1394237f3c91
InNoiseEP = f3add13126a14ead16967a55997c47a25801efca5d3a8633f38ca2bacc15aea13b784a90c920c0ffe1519e275f8051fe6133ca42b6184899c44057c686c24b85e2341017714d72231f95105209269c6f5a6b1c6b1fdf0e82048d9b5b8ec355996aab3fdf5ed55e44b64a48d0421dcd69464568827a3206f41aa0f444b2b197025d03b9dea0c442ac07137e85854239248d080f3e9f4aa8ca86039d519d45b2d424e5928ab6b39a6658e65bc119006672daa2cb0c54783e455456c43862d10b050a2d1611144d2b5b21d6668129ade5ef1165ba58e0769c2d31fbd19ad144cc38566e243b83362d51c8d72937e54d10db9e4428f4aea5ab7c22d22d07079698d671a8b7b58edfc181d53fafd1a2c0034d8c2382807b85f82f9a025320ea7d768da0cd03aff8b7eeac270883cd27dc664976e301524aa8eec82da0163cd6b8b456881af113349915c5ae9515156bdb820018c6b895c2357e93e2e1b04acc54c75fae61ce1882666ad3a95f7d10b32c73f2c3f97d215c34a36391059742b597e0c26a30103b8824311500dc416a33c68328266394f16a57b684c21b2b785f77eed6e7c5ad1f7967b6095912455c48cd96b6a2629a82ce277c3a0c2b01bda0e02d6c201b2f249e6d4ecc910fa38c6d703b868a637f050da4c831390bba28b65f39d48824bbe88402c6794a2c4f0b63b713f09c69592cc79b7e5e5b224fb8a38c9c2581e7602e5039b64ca7f468e99e1f6bef7878842d5ba1cbe54c5dae6ca7c360ea8488681bf48850b805bc82a1d07bf630d90188aa68cd1edfc22df57bf1abed5a10f230f1089a40c531a841a15e094615c732a42a4005c3815d2d272711079124400f23e9a7d0f112c5db8f02b958621ce6c7d6010c35249fc5c06e2c505565de5708a6448707c9a5ff0943b709c046fb2d00c5e2b4b356f15bd0ac0d2af0d237134acc6b2ae5b2d9436870aebe62f26415966695a42011bf301775340f52c7567924b9d4e977b8d03121afe7b5f111d9a5a6235f054e8a98078d74d4ac3a6b7d4b5b555e6d870c032b8b4d451898abef511add7a235c6aa3d62e2b40e757b876c6ab7addbee704cd39beaf3164495a95de5083d4a26833f3a75e397c58598a5e484be40544ff1def8329806948c94238f5ae0f38d4f287748ea04e1c74e7b9f45ca426cdc8aeda5c940d7c3940e68926d4523a5c4ab89fefe9109876064fd710bbbb18b24a9f149a8752a28d4284346bf1b76382ca69f000a6d8052200ad202464d44072820c3f012d280b310951d2593624b80485504bdc25749e166d929824057869a763f9849671a349267b8ae75a7fb1274b53f02d3f8f98e822ad1461d35faa83433a1f2e0eb3598ef23f0aa765b6f96506fe50be77dfac62ef0f74d0db752d0ba8a0586eb51d14a83e69ce197318c08562b3727597ceb25b48fc395211c262f618590d834c602b4c6e81c93fe3f8558272e25dc6b184a01f8cb5e5b7d66c102c7a47fe55535067690440b2895bc96b5b73ea2fcca448e9dd389b725e91c379f296e313d6e44c40b575aed932fe628341c066f36dd8053d81776973448191a3f2b5cd8c52e3a3a7416bb234a59ddf2567ae92839e1a7a71aa0d175f0503729a1b6f5fac31ba5552ad481ce0ce8208ea98ea3a33c1acdce0c31a45f06c8c10cd4127f24edc116a13db464a7fa00ee7f92629918db067ed9e4830ccb830a95840971a492a838217dca136c9149c2f245cda65f58c4996d12639049a648ec6845518488e1ae8f4d23c14102b9d90b38b6a1b47d44cc7fb458a230e59c4d42e366414b6577bd567c7ec70d779ed277ea4d3e7107a1fd20d9ff85289bc7d626264544aa8b24dee58a94e12871b23ab97945f630a6125037087924399a8a60c8a66599f82c1c496078ddfa400e0be15a41849d940a8941d10a322d951b98522cb30426092c5419882e06fa0cc41119b3e540e240c506d2898305b5ed2c9324310c530d67a7072870269aa338db4a26551122f62abe129fcb8f0163975cb8636360ca331d966902b9d28dcc016549942310209a7c64f261e998f6421c074007adee784c4beba5fc2f1c5a9a6a40907dea8dde52c3c99b330cede97e06a4421bea9a073808d351d2d411d63d1ca113939ada555263e455c7e19a1d8c9c271fe402191dced3d0c01718607185a329e42216de02d9857da9936f2b2bc47076b6bc92672e831d66060a5bed6b077abe2301a60376418a125e9216888f5e151858c3ee799794ba347f5b26c18608c93f2b09d0e87d8ad03521c1100181581e617a23466ae3496878cadfe5922250226403c0706204161ab546ff9875c910b694c69f0d3c08a901fd3e8f79e052feb55d1010c58d590b8295ec6b09f586577ba1e2f900ed856140020aaa1f8e25945bd91add9b0109a38f75fc886ab422a37e673206c8612861e9093d2f20293c7a42346b05e32d14f177f8586c74492e0f27e04376f88c61f6c27c302f5c5866d96a36c53d709b63aa94e14ba4fc43e5c8edb93cf08a1
InNoiseEPP = 00b000000003c0ffefffdbff0600038000000000c0ff2f0000000c00010000e0ff0a00038000000000000040ff0b00ecbfff2f012000f0bf000000e0ff12000680ff1b0008000200005c0010000180ff3b0000c0008000c0fffebf01c00060000000fd6f004000080000c0ff0b00fbbf05c0002000080000c0ffdbff0200ffafff2b00000000f0ffcbff06000280ff1b00f4bf00f0ffebff02c0000001d0ff0a0001000050000c0002c0ffebff0e00fe6f0010001800feafff5b0000c002400020000000003000200000c0fb6f0000000f00020000e0fffabf04c0ff1b00f8bf00c0ff1b0000c001c0ff4b000800fdeffffbfffabffdefff1b000c000000013000f0bf0080fffbff0e0000f000e0fffebf0480ff1b00f8bfffaf003000f8bf06c0ffcbfffabfff6fff0b00fcbffc2f00400000c000000130000400020000dcff120001c0ff0b00040002c0011000fcbffbef000000f7bf01c0fffbff0200fd2f000000f7bf03c000e0fffebf0300003c00fcbf003000100000c0fe2f0040000800ffef00f0ff12000200000c0010000240014000080000c0ff1b00f8bf0140ff0b0000c000c0ff2b000c00000000fcff0e000140003000fcbf004000e0ffeebffbeffe0b00ffbffbef000000fcbffe2f00000000c001000140000000fe2f00fcff060001c0ff0b00f8bf0440001000fcbffe6f0030000800003000000007000140001000fcbf028000000000c0010000fcff120001400020000800ffefff0b0007000180ff1b00080004800030000c000580ff2b001000003000fcffe6bf00000030000400ffaf0060000c0000b0ff0b000700020000000000c0048000000008000000000c0003c00240023000f0bf01c0ff0b0000c0ff2f00000017000440ff0b000000014001b0fff6bfffafff0b000800fc2f000c0003c0010000e0fffebf0240ff1b00f8bf028000e0fffebf030000fcff02c003c0ff0b00f3bf0240ff2b001800ffaf00600000c003c0000000fcbf034000d0ff02000080ff0b0003c0fe2f0000000700010001200000c0014001d0ff02c0004000f0ff060000b0ffebff0e00fd6f0040000c00007000000004000030000c0003c0ff6f000000130003000010000400fe2f0100000400004000500000c0fc2f002c0000c00040fe3b00f8bfff2f01f0fff6bf030000dcffeebffe2f00fcff02c000000020000800fd2f000c000f0000f0003000fcbffdef01f0ff02c001c000f0fffebf0540014000040000f0ff1b0004000300002c00fcbffeaf000000070001c0fe4b000c0004c0ff0b0018000100003c0000c00100000c00030000c0ffcbff02000140000000080001c0ffebff02c0034001f0ff1200ff2f003c002000fd6f0000000300fe2f00dcff02c000b00000000400020000c0ff0e00014001100008000030003000100000f0fe0b000400054000f0ff120000b00010000000004000100014000380ff0b00ffbffeafff0b0007000040002000f8bf00b00030001c000340ff4b00000001c0ff4b000c00fd6fff2b001000fd2f00e0ff0a0000c000700000c00000010000ffbfffefffebfff6bf01400040000000fc2f0030000400ff2f000c00ffbf00b000f0fff6bffeefffdbff0a00ffeffe1b0000c0ffafff3b001000fbef0100000f000200ff0b0003c00340002000f4bf0040012000f8bffe6f0000000c000440002000fcbf010000300008000400fffbff0600feaf001000f8bf00400000000c00ffef000000130003400000000f000280fe0b00f8bf060000300000c0034000e0ff0200fc2f000000ebbf00f0000000f7bffeafffbbfffebf06800030000c000040000000fcbf003000400000c0010000f0fffabf007000f0ff1200fc2f000c000700fb2f01100000c0007000d0ff0a000180ff0b0003c0fdaf005000f4bfff2f000c000700fe2f00fcfffabf01c0ff2b000c00ffaf00e0fffebf0240002000080000c000f0ff1a00003001a0fffebffe6f0000001b00fc2f0000000400fdefff2b00000002000110000c000200000c000300fd2f00dcff0e000400ff1b00f4bf0070002000040004c00000000700ffef001000140004c000d0fff6bf01000200000400fd2f002c000400feefff0b00fcbffcefff0b00f8bffe2f006c0008000040ff3b000c00054001e0fffabf0200001c000400ffafff0b0008000070ff0b000f0006c0ff0b0000c0020001d0fffabf0440ff0b0000c000c0ff3b00f0bffbaf00000017000480ffdbff1e0001c000e0fffebf04c0ff0b00ffbffd2f001c00ecbf0000001c0018000300006000fcbf02800050001000feafff8b0000c0ff2f0080000400ffef00000004000380fffbff02c0ff2f00e0fffebffeefff0b001300fcaf00a0ff1a0000800040000c00003001000003c0fdefffebff060002c00010000c00050000f0ff1200007000800000000600001c001000007001000004000600ff1b00040000c0003000080001000000000f00007000100004000000001000f4bf
InRand = 452a15b4d9006730f0a433be2d84ea6706f03119ad2410292922375e0f7d2c3a
OutPK = 5696358110206fb1cced54bffe3e0fa80884f17ab7572dfdcb8b290fd99c29c74d007d68410e52899001aa27e511076d11acda1ee6ae52b3489831c4ccb89b331bef19c5beb666d2f331fabc0e96d4bdf5815d394ac99bb410a83e29c731e06c5403b0075cf15ef20edf09ea6a012aaf589a1f670cd6adf8920f177155aa0fd094c101c5487c682f0054152fa2676800673843820172f8cf5c5a64d47a881fd69327cc4885295a5be6c2805acbc8ae6cd8c6512d9e94f84baec76f419e03a272132c3884840610f58fd6bf6893da49d4549d5c0e87d28a417097daa1917c691b08076564d1c6683a139792e6da65d66115026755730d9a61b9f09ab158cece142fcaaf42d56397affd9a7ba6f8c40c7e5cfcd48b81a9b6819ed631c709f28329823c4a64947a3bcd47920dfc949b56eef44c9a256ed225da70d8245c444f98a2c49e3ca97b4632d8155d14aa35c7cc6051c57aab4ca84a24180d3adb15051a49afb9b6982a1a2ce99137297eebe64103fd51646cd6dda0f612268607e1f6aa213adb97a595ec6d9ae20730f6d12da5e6d6273178a294030cc3a4427eb2a1ea9d3a262079eee0165732a8460116d76ad5695dde58dba1edeaad26643a67b3c815970911caa9189244558e20083d1783d7c85aad881bc3cf6194cd8a46a7560c74d1a81df1c84832c91d2e3ad98669b709757d08b534b356b5f0948572bb9023dfdebd5b3650bfa995a4965e3d45e84c06e7f15d731264eebb01c10dd3a7381661cc9491ac3e76efa0ada251c9f79790549f2c9af179b91b44533cc8b2f67f7d6f587bb3c50ab14634ba8d8e41cf4a58a728f55c2b87fe67d7580e8aa3ed249284244f97a693e35d67ac1a00888ee63482107386ccd2023d9465bb7671b3341636a856b8b90aa38b78f25e434c6d8e6b0b20633de72e63750d834ed714e46f7dbc5d14046692850a9846e28518ec0cb78e4fb15bbe3738e852a6d84876fe279266621a5fb2c65453e33e9eaccc95265a668266a6c0ab15bd1a70c525e18f6d0dde6fcb4b23e5b8a8a715e05060209d1f89fa07b1816181f740ded8271e059018408e5a2044df41f81db0376aa2aae69dab1b6e88675aa578f8d5d243e838a231859364cb409fa21042196721a0af53d1a98d82886ade64b64d316204e4d6c7a5389424aafbb787823d87e1f379d5a6622b870e852f7d8db69f14ab905a153dceaf291034841ddadd53129d010b6ff232aca879c11e45c02095394cecc045a70d8ff5c57ad14df16b0c15009476986ffb93abc8848d79801ced33e3f03e37811a545b6808e9461f7a2752afadd6db15e316a599c8979a05c849d54345f83dad8ad8d10bd1f9152dd11884bb981273af1e4ae5386eb33e8f2b7800267eb78f71ab0cbaa05d8fc13be72c5aaa46bf089b5e150b967b17bd242be86df331e7c911a9cefb9b16fc5379c1bb0b8481b3f0ec7ec3fa3a956ac47e1ba69db083055e56c32941e1efd032bd9e413b63737bb99130ec99b1035509ac4611fa27afa265f9e52238e7211e62d5e1faffca7e8c4552967bdca8c32de81545767b5f033a21d1b07131e5ce85f3718f4bd00518f08946854b2e667f7e49291196a5400450ef446eb76ae05f7e1e52f56c49725bc087a3c7288e931d4d87a8ca8e651e7f2ab0b008c56f68a01fceaed626ee5666722603247f6bb2e05038e93c70e1cda82fc2edc3ae5ca6b622ff4af401b7f4c09ca4e9084ceb2812b8ba36435dd1cf55b896250824351149445d6fdce499c6ec94f19bb6abefb2b6fecdb7c90985b93d8c068373210d1ca87d09dc9e78d81b9d2659f939ab1e59b1a58009f468ff887c489fcd4fe3392749554024995aaeed8d57846ce261c0776d540647e8484de8c780e02725a37540f3e216456cc40c5d14e3b412cf5167937bdda6d809727ae5483f715acfd9d422488a1c0bb553ed8a83cedce18e427905c58bb998fdae6fc377f155185d085f83a71364430d275949afa59f4294e7718b56b24a67b114ee7d5c945741c710aa191b202e43ba894917a21fb39266a1995e8e0017007f281bf8781b02918e4b27f6f36d75ddc0c767349a31d35c3af3d8b52c5bdc2e01a29566f1cf94f256206e1d8afdd3f7c20a6a6d98c46b8101fd648484b5fc2f038dd4d8c410a0f3976ad0499873bee69c131d0daaca531a853fb661798967ca011d7251a234d6c94e326217fbc72e364fd02f3f4336e5afe5dd6ee6ad9a411805dec8a2253f778d89d29c2a5d76a544f30818b32d8c5710224090f32a28bac4b2b04920cabb12514ce5d34de66b627ae1a524974c55990a92bd4a01bd0fd7c8fa527b7236421d99b1df396912895da67132bd48158ca540a69c962c222019a1157dc90639743522db4e4a656e307817aa52632add1b026ce82709e50057d81c5bcd3080806ea630a1740bff4cc938b434475028cd1084ea6b2595f77a165a86b327e9c9f2dc0e480934fbaf86951269c5a6c1e9873a16e38033555be2dc4063144d5244e8f3fab06442
OutRec = 02c00030000c00000000300008000000002000080001000020000c0000c000300000000240001000000003c00030000c00020000300004000000003000000000000020000c000340002000000003400020000c00014000300004000240001000000000c00000000c0001c00030000c000280000000000000400030000800028000000000000300003000080002c0000000040003c00000000c000380002000000000800030000c0000800020000400008000300004000040000000040002c0002000040002000000000c0001c00000000800000000300000000300001000080002c0003000080000800010000000004000000000000000000000040002800010000000020000200008000200003000000003400010000800008000300008000080000000000001800010000c000340003000080000000030000c0002800000000c0003c000100008000300002000080001c00020000c00010000000000000100000000080002400000000c0001000000000c0002c00000000c0003c0001000080003400020000400030000200004000100003000000000c00020000c000380003000040001c0003000080003800010000400028000100000000080000000000003000020000c0000c00030000000000000100008000380002000040002400000000400018000100000000180002000080002c0002000040003000020000c0000c00000000c0000000020000c0001800000000c000300001000000002800030000000038000000004000040000000000002000030000c0003c0003000080001800010000c0002000010000000010000300004000040003000080003000020000c000340001000080003c00030000400014000300008000080000000000001400020000000004000100000000340003000080003000030000800030000300000000140001000040001800000000400008000000008000380003000040000000010000400038000200008000280002000080003800000000c00020000200000000000002000040001c0003000000000c00010000c000180002000040000800010000c000000000000040003c00010000400004000200004000200002000080001c00010000000018000000000000000003000000003c0001000000003c00000000c00008000100004000240002000080002c0003000080003c000100000000080000000000002000020000c00024000300008000180001000000002c00010000800020000300000000040000000040001800010000c000040001000040001c00010000800038000300000000200001000080003c00020000400010000200008000000001000000000400030000c0001c00010000c0000c0002000000002c0001000040001400010000c000240001000040002400010000c0000c0003000000002400010000c0003400030000c00008000000000000000003000000002c00020000000010000300008000200000000040001c00010000c000340000000040003800020000c000380003000080000000000000c000280003000000003c000200008000000002000040001c000300000000040003000040000800000000000024000000000000100002000000003c0001000000002400020000c000180002000000003c0002000000001c00030000800038000000008000240003000000003400000000c0000c0001000000002c00030000c0000400030000c0003000000000c0001c0002000080003c0000000080001000030000000020000100008000300003000000002400030000c000200001000000000000020000c00020000000008000180000000000000c00010000c0000400000000c0003000010000c0000400020000800000000300004000300003000000001800010000c0002c0002000080002800030000400008000100008000080000000000003800010000c0000400010000c0000800000000c0003400030000000000000300000000240001000080002c0002000000002c0001000000001c000000000000240001000080000400000000c0000400030000c0001000020000c00000000100004000280002000000000000020000c000380001000080000000030000000020000300004000080003000000001c0001000080001c00010000c0002c00000000c0003400010000800020000200008000080001000000000c000300000000340002000080003c0001000000003c0003000000003800020000c0001800020000c0001c00000000c0002000030000c0001800000000800014000300000000180002000080002c000300008000040001000040001c00030000c000140003000000003c00020000c000240000000040003c00010000800014000200000000240001000080002c0000000040000800020000c000240003000080002c0002000080002000000000c0002c00020000c0003800010000c00018000000004000080002000040001c00030000c0002800020000c00
Key = e99667992da3a284dc25fbf5e0856d5877938a2b7e96172e49f5b6cae78afb8a
InNoiseS = e5c40729d83a968c6b2ae550c89b6623e77579f20c14a6c8cb4a623b25da3973ebcc3ee5c92a34345957fe5d10827aa05da022a399332066a2679d11e83e00ac2be799dd3eb7a6a4c787e0b59fee900013ac050b77cbda453cfd06f0de51694b12433fdc32e37b16a8e60d2bb02b82101415850212b676144ba4145ef47731af3419fc8e406be62485d7da056868435a8d1c6a52823fd4ff3db975998aba564e7274525407c318a604a4dc1360c6629f9d425963019f2c9d05901e38abfe87ee51e4ea7c8591ed84c2f991669d6454d9a1b3b88e41e9309e94ae8fa797a91e27fe08f09a2c5e826b44b1626bc88098a4280428c05ffd8129939d450bd912784ae55e13c7044bc593e9406c1ec0c262ca59f225f60a812217471d1fe6af221c98a43135f6f6696441f17b698d92702f811702ce6b292e852723d21f996675c77070427be30a70f8fc8decd69c94c19c88949ac9b528261a26a77016952a7e91a17ea81be4bc4f2175d8b44835472e1606d0059a2e4d86c236cd9c8f27dbe9fb71800b5c335862f62acd0bafa1aa6821d585f7e6b4a5718a6020d4c53244b99d80718a09621766b7c158ec90cb0dee4bd630a9264a49db854e3af0126b17359842956ccca27e498df495c220ab9968000c021a7386464f958f8691a66c671186a26e484f04e5b29112e409ca5f366091d69ab4492f52e8f6abc7e561394ae89ce050bb776b7c3cb3c334f9e5da9fd3af1de2c68a2109ec683976a24cc4255139854c4a482fb8555e926c41a96db8f62e62f4ae6783bb48622a8e2373c7b0252dc40d52b1713fc48b0058b1f65a0fcdb3b8d07c3febd7eed55021773a58e9017aa90934c55f5799d53ee4aef2a8cb2209c01fafba6151be916bfdf15862204c52adcb0da5231408ebca29c02029cfda60baaa5aa09da3f3719495fa8de6107a6d175b030d8b84fe4e5b4f17032f447a20695f349ce8124d868eb7f2dab6820e6f78115c53514ab631f6fdbf3dda71b1be890d12e5bab273a9312d2afe739b6d75c6cb6446c445aa0198eb862748b55de2054acdf0b54bcd323ac6f27f4de55e197f7517210142e179d81afc501a88661d89be6c7e6aabac160704a5b6c1a2b829d9ce7486418fb92cfa23bd1ca3872a0b67b5ce4c62caf1a495bc442c11cdc87c06563d1a73941ae907d46ab77059166dcd11d12221582bb49ae411debc6cf36a9ed3c68643f7c18af0cf107e7dcabbb221cc201023a6156bdabde7e9b12bb3c64e0f0fb92a87ba2c59dcb8a5d48d97fce343ca0e69210b1c4d01897141ec4627e3a7ce05f848c4c558e0af50c36c053b100df69532935f46293a29c5c8e24ca3ade25bb427712f80263b736a6403cdd4c47b284d22ba4575d066d202d498e86b6ec23dba8abe87f63e375b0b6f41601c68fa1717e67b654ca21bfb428a0ca7ff5d2f51447e05a56e550a6790657cc3b0c736922fbd21b491694a64a11f45108b605f06d8610686f2912f504ff07f313edae07930cf8a4e838b0606a402625c494205fdfa764a5a9416853548364b0cd84ede3d3ae49af22f4d01ab127d31264eb8ace5d2554e55290a2d8979aaf88a761582f5c92a19f49ee4f573d54a61a638703e7535eb465bb6fa3a3dc1ab5cc452d826ef6e818a65aa842f1b60c57a50354fdaf1518f4d94c088ba049a5d963105f2a8e0819da6192361240474c5cebb328cdd907a2e04b0bda41c720c23c808a0918e68fb83dfe12684a4bb471eba7a0d48e75847a44042220ab85b412048da1981306d52fc659f34876d16ae89ccba803080b9268a8597bd57f00dcf79012cbb0528f9830864a129a5495879d228ef86fbc5bb39ac450b196a97200a1829323781d64fe981fac57b5228719adff3ee5e72c29af5a18d3e9635574cb65b4086e92fbb1ba62d36a823139955d186f65d05b6bc3915e5061416f548837d532a453aa50eb26848121a3a33aa5604c678249c676c8ec973c558f2e8ef88fb105998550da3cffa09838974403e8610370b2937bae154f488bf31c816890c83b878cacc577f2a3bb256687025c17cd595614fd2e803d1fa2891634772badad84549a71a5ae83e3b9418f6f9f6ca6d4a67d9c30459554bee4ce413091e1ca092a507d9685fd259d5f0b991d0645dc6d48a1fdf8171aa8e4c210c6cef97360155acdbe19b55f000012120e221240964cdf57b09900791e02f5168ddb798e3bdb1056298ef04d00a1bde9653e073e8899530db2d30961a4a58d604ae055ab56e5a0dcb77403a41e51b5d0895c675900c9e253d1851e9d87eabf235056bade602f0952ca1c8dbd5cd4a59324d5dfbc309518b5769926a4c7863c51db8a4249c6fce71c92b9c086c217f987a38569d923b01f58c3c3682a5a796223f89c7262160226cd8ef3730ec71a43d4e3053b2f15b855e3934501a90bfc6bdd9c3d6003ce2d86076215ce2db3e31bdd2266c8693e020129d63576617d3c68127608b7566b4be9dab7576b4167fa0cf610180153207d5ff9413488a
InPK = 5696358110206fb1cced54bffe3e0fa80884f17ab7572dfdcb8b290fd99c29c74d007d68410e52899001aa27e511076d11acda1ee6ae52b3489831c4ccb89b331bef19c5beb666d2f331fabc0e96d4bdf5815d394ac99bb410a83e29c731e06c5403b0075cf15ef20edf09ea6a012aaf589a1f670cd6adf8920f177155aa0fd094c101c5487c682f0054152fa2676800673843820172f8cf5c5a64d47a881fd69327cc4885295a5be6c2805acbc8ae6cd8c6512d9e94f84baec76f419e03a272132c3884840610f58fd6bf6893da49d4549d5c0e87d28a417097daa1917c691b08076564d1c6683a139792e6da65d66115026755730d9a61b9f09ab158cece142fcaaf42d56397affd9a7ba6f8c40c7e5cfcd48b81a9b6819ed631c709f28329823c4a64947a3bcd47920dfc949b56eef44c9a256ed225da70d8245c444f98a2c49e3ca97b4632d8155d14aa35c7cc6051c57aab4ca84a24180d3adb15051a49afb9b6982a1a2ce99137297eebe64103fd51646cd6dda0f612268607e1f6aa213adb97a595ec6d9ae20730f6d12da5e6d6273178a294030cc3a4427eb2a1ea9d3a262079eee0165732a8460116d76ad5695dde58dba1edeaad26643a67b3c815970911caa9189244558e20083d1783d7c85aad881bc3cf6194cd8a46a7560c74d1a81df1c84832c91d2e3ad98669b709757d08b534b356b5f0948572bb9023dfdebd5b3650bfa995a4965e3d45e84c06e7f15d731264eebb01c10dd3a7381661cc9491ac3e76efa0ada251c9f79790549f2c9af179b91b44533cc8b2f67f7d6f587bb3c50ab14634ba8d8e41cf4a58a728f55c2b87fe67d7580e8aa3ed249284244f97a693e35d67ac1a00888ee63482107386ccd2023d9465bb7671b3341636a856b8b90aa38b78f25e434c6d8e6b0b20633de72e63750d834ed714e46f7dbc5d14046692850a9846e28518ec0cb78e4fb15bbe3738e852a6d84876fe279266621a5fb2c65453e33e9eaccc95265a668266a6c0ab15bd1a70c525e18f6d0dde6fcb4b23e5b8a8a715e05060209d1f89fa07b1816181f740ded8271e059018408e5a2044df41f81db0376aa2aae69dab1b6e88675aa578f8d5d243e838a231859364cb409fa21042196721a0af53d1a98d82886ade64b64d316204e4d6c7a5389424aafbb787823d87e1f379d5a6622b870e852f7d8db69f14ab905a153dceaf291034841ddadd53129d010b6ff232aca879c11e45c02095394cecc045a70d8ff5c57ad14df16b0c15009476986ffb93abc8848d79801ced33e3f03e37811a545b6808e9461f7a2752afadd6db15e316a599c8979a05c849d54345f83dad8ad8d10bd1f9152dd11884bb981273af1e4ae5386eb33e8f2b7800267eb78f71ab0cbaa05d8fc13be72c5aaa46bf089b5e150b967b17bd242be86df331e7c911a9cefb9b16fc5379c1bb0b8481b3f0ec7ec3fa3a956ac47e1ba69db083055e56c32941e1efd032bd9e413b63737bb99130ec99b1035509ac4611fa27afa265f9e52238e7211e62d5e1faffca7e8c4552967bdca8c32de81545767b5f033a21d1b07131e5ce85f3718f4bd00518f08946854b2e667f7e49291196a5400450ef446eb76ae05f7e1e52f56c49725bc087a3c7288e931d4d87a8ca8e651e7f2ab0b008c56f68a01fceaed626ee5666722603247f6bb2e05038e93c70e1cda82fc2edc3ae5ca6b622ff4af401b7f4c09ca4e9084ceb2812b8ba36435dd1cf55b896250824351149445d6fdce499c6ec94f19bb6abefb2b6fecdb7c90985b93d8c068373210d1ca87d09dc9e78d81b9d2659f939ab1e59b1a58009f468ff887c489fcd4fe3392749554024995aaeed8d57846ce261c0776d540647e8484de8c780e02725a37540f3e216456cc40c5d14e3b412cf5167937bdda6d809727ae5483f715acfd9d422488a1c0bb553ed8a83cedce18e427905c58bb998fdae6fc377f155185d085f83a71364430d275949afa59f4294e7718b56b24a67b114ee7d5c945741c710aa191b202e43ba894917a21fb39266a1995e8e0017007f281bf8781b02918e4b27f6f36d75ddc0c767349a31d35c3af3d8b52c5bdc2e01a29566f1cf94f256206e1d8afdd3f7c20a6a6d98c46b8101fd648484b5fc2f038dd4d8c410a0f3976ad0499873bee69c131d0daaca531a853fb661798967ca011d7251a234d6c94e326217fbc72e364fd02f3f4336e5afe5dd6ee6ad9a411805dec8a2253f778d89d29c2a5d76a544f30818b32d8c5710224090f32a28bac4b2b04920cabb12514ce5d34de66b627ae1a524974c55990a92bd4a01bd0fd7c8fa527b7236421d99b1df396912895da67132bd48158ca540a69c962c222019a1157dc90639743522db4e4a656e307817aa52632add1b026ce82709e50057d81c5bcd3080806ea630a1740bff4cc938b434475028cd1084ea6b2595f77a165a86b327e9c9f2dc0e480934fbaf86951269c5a6c1e9873a16e38033555be2dc4063144d5244e8f3fab06442
InRec = 02c00030000c00000000300008000000002000080001000020000c0000c000300000000240001000000003c00030000c00020000300004000000003000000000000020000c000340002000000003400020000c00014000300004000240001000000000c00000000c0001c00030000c000280000000000000400030000800028000000000000300003000080002c0000000040003c00000000c000380002000000000800030000c0000800020000400008000300004000040000000040002c0002000040002000000000c0001c00000000800000000300000000300001000080002c0003000080000800010000000004000000000000000000000040002800010000000020000200008000200003000000003400010000800008000300008000080000000000001800010000c000340003000080000000030000c0002800000000c0003c000100008000300002000080001c00020000c00010000000000000100000000080002400000000c0001000000000c0002c00000000c0003c0001000080003400020000400030000200004000100003000000000c00020000c000380003000040001c0003000080003800010000400028000100000000080000000000003000020000c0000c00030000000000000100008000380002000040002400000000400018000100000000180002000080002c0002000040003000020000c0000c00000000c0000000020000c0001800000000c000300001000000002800030000000038000000004000040000000000002000030000c0003c0003000080001800010000c0002000010000000010000300004000040003000080003000020000c000340001000080003c00030000400014000300008000080000000000001400020000000004000100000000340003000080003000030000800030000300000000140001000040001800000000400008000000008000380003000040000000010000400038000200008000280002000080003800000000c00020000200000000000002000040001c0003000000000c00010000c000180002000040000800010000c000000000000040003c00010000400004000200004000200002000080001c00010000000018000000000000000003000000003c0001000000003c00000000c00008000100004000240002000080002c0003000080003c000100000000080000000000002000020000c00024000300008000180001000000002c00010000800020000300000000040000000040001800010000c000040001000040001c00010000800038000300000000200001000080003c00020000400010000200008000000001000000000400030000c0001c00010000c0000c0002000000002c0001000040001400010000c000240001000040002400010000c0000c0003000000002400010000c0003400030000c00008000000000000000003000000002c00020000000010000300008000200000000040001c00010000c000340000000040003800020000c000380003000080000000000000c000280003000000003c000200008000000002000040001c000300000000040003000040000800000000000024000000000000100002000000003c0001000000002400020000c000180002000000003c0002000000001c00030000800038000000008000240003000000003400000000c0000c0001000000002c00030000c0000400030000c0003000000000c0001c0002000080003c0000000080001000030000000020000100008000300003000000002400030000c000200001000000000000020000c00020000000008000180000000000000c00010000c0000400000000c0003000010000c0000400020000800000000300004000300003000000001800010000c0002c0002000080002800030000400008000100008000080000000000003800010000c0000400010000c0000800000000c0003400030000000000000300000000240001000080002c0002000000002c0001000000001c000000000000240001000080000400000000c0000400030000c0001000020000c00000000100004000280002000000000000020000c000380001000080000000030000000020000300004000080003000000001c0001000080001c00010000c0002c00000000c0003400010000800020000200008000080001000000000c000300000000340002000080003c0001000000003c0003000000003800020000c0001800020000c0001c00000000c0002000030000c0001800000000800014000300000000180002000080002c000300008000040001000040001c00030000c000140003000000003c00020000c000240000000040003c00010000800014000200000000240001000080002c0000000040000800020000c000240003000080002c0002000080002000000000c0002c00020000c0003800010000c00018000000004000080002000040001c00030000c0002800020000c00
Key = e99667992da3a284dc25fbf5e0856d5877938a2b7e96172e49f5b6cae78afb8a
InRandA = 466e66f041312a755f555a949a661f8966f440cc2d3a4cfc08ad7aa8f018a681444247d0dd37b2ea61a2496ad9880bdda2c2c41895f83180f79cda5ba1f202f19896aa9ba51443ab58f7349c1fdecef93b444a9996a13d716e709efd1c08e2e2768daf974c78dce6a18b5eb9ba8db402ad955609740425aa21457adfe5802991075b62dd62ee55135b4040a3b32147748e9980e0958736c66c24262cbf55c782646c255712e4665ff80576774d420f4e13892016e6530001df93fab40ed9d48ec5d2d44726cfd0dab47094b8dbf0da6da5b4f7534e680166788daeb2a7bbfa2f746fbab1346d3f3d8f82d859f973661c3c6bb624bc0ed2de274789275110fe50b9e18ca5196040006e9dc78be2bbf1214e6e47e305f54e7d1b51450781123ae01ba6774ca51a7745f2a68aa44e37a8d6444fc03aca490fd4a1aa02908a51e1df4cbc1d0804d70f9d94859b01264cea842da37d86fdf97f5cad10b03aee627545aa02c3d67f07de5f63624e45615308a8e81d55698851ba625188624b032aa52cbbda9c80f715897fc86d300b527d303aeb03b8b18440b21e2b0a682da5740dc9c6863a5a1606ba784e2e47a4ca2fb09bbe641346d533e82c221d6fbbd29a2cba99d71fc153959c62985bb092de06c2253a032ecea0f6d8bb041ac2236a98f51a7220a73c52f4498d153ad99774883f85680410944030fe28204db6ba2a454a0928b10af2b920b3658e92c3bdbcf4681c7993f2aea59c419a979687a3ac2180f94c8e50c293b627c0216f5c0ffa2c310b7d49ccbafa14875e8a94b3ef1e3ad7926db6eafa0e87cf04a8f5101a8407f0d7e731ae31ee23f14c09609c29e254dc781588648e89abe662fc5a79e30cd8559bae7db123b96f4dd878526374311b681c45ddad6d96a520a13d6860e967e3f7daa8718f86f5c4cca4309f5caa4646b2ab5787033553b4149de6d63aa4593a70e6486b0c3d4d02dce897d0e14bfa6bca6b261176ead285e7007905672a76754c8d66414d99781eca5f9e83fe7bc3066c139eb909d3156d79d1860a2650149683e34578f272bd185a93b0418e50844fc04b253504e8e2f7a60a50c1ddeb747c357f249164d437e0bf53a8df2a01a836fa69d85893ea895c449fcb7e6d7c9f24565848b97f529e376885a219640774898a96aaf7c1260b871246949f6874c23e28e2adc98b3d6e4fdf8fc091a45e75ae6503f535f4b1ec20f66b61152f63dd8e3bc512305a0cfe9bd09a5c65910586123a246cd8188764c5895d278ba01f91196f4c68599cf1b3b800c37bd3f813a5ce326b0d9952ac4b6b96bf2468de4837157451177dab8ccb5d90591f5c81f5d8f14855a22ca4e89522fb4ff333756021f4c3b5245738293d8c81d4b0dc7ed618ac14c712350ed97d1685388ec2e14317a2295710418889fc3e214d2d225869509b068ca5032af80db7587b759b4c073069a4c4fe9a8be40f39d500667dc720b90a2ee17785644a6a3be55f51260736ad6525d7e121f413165bb38142621191b7f21feddbb8a658cd013187b246051ccc0cf952f574148317571a6643666d9fdbd4fd7ed343519b791c131c68ee85850595339c962335351744db3738569cb5bd42becb2e3c0c2be214592d1aa3f1d3cefb6b364896cb12096b2491df4381d50ace9f766cf140fb289a5b6415f0fa72548ba6e54a5da261bd2606150ff6003c87af1a687512645cfcd2cb555962d59c5affec340c9460218541228c99df057601824715f38ba0a27f945125fa1322a02c4b0e3388866cb349f4d0a1e423cf20d41055a46be20e0a43d70183de531537c9ec0229a65168027494f19a4ce8ace666298bdbe3db10bafb4661d7c9f8b70ca955d7054a25dbcc6575a18979ce4d42118039a739811429d0e26f4f6b842890e47c6d5178d5f2ccac590157f9b35aa0746b9c9353181a546ecfc92131ba556c1638a9529c6688f037ebf8879e15ebaae9f881c9db1143d7509b2b8ca242ecd245dc0898f847b96bdc4c273908a2149817eb2bb0aa9963e54007767ea0afc0d9508f0e5039cfa257f19cb57898c52737f16958e30101d289a484e7e460643409126c6610a15570648a40a0233cbdf863cd1384299f6cd5b8a88c700bff8faf80bf35874a024db6164195bde038e2f61c4d9e6994643ef0923f6c795a8f2a9d24a2bc391b4046b8cf4bfb40287893254c493a70434b12af36c64d645ccd6e4bd8c003674bf315e512bc9d21b6121ad11a790197bbf5b453f8443449012544e02c5045705c908a89f2d1faf0309d0aae891efc1717aa3f32ce3645138c13125db68d06effa6436359783c4d863702e6b2b4f7eea76a4504a8d01d39ab252d66a64f3b19186fc5918f19d4a36d2415aa943d267cb5d4673990e74fb8ed8484af02df782cd23e302574069aba1a631959be32831c3a27b35a3ff909de8a1fb2a6c852fd05affdff5fa11ce353ba7a3b1e1920bb62c497acdea0243431d8ae65459e867aa8082d44a5ac8fee3bd3d1653dcd0d209a62c
InNoiseS = 55d10f4b48067ba8ef2308defa0285cec13987c82d528761f851ce55ef4f40659ebd2f0b6deae54a28ad4dcdcff387b99a8e4639c0cf354127186a92f6c0b1735f6d34d89596800646533332b2e5dab016a3d5129f8702223a94003c03774bb2061d322a86d3b7727904414df6c1c03c1a680863a43a09a862e6a0a0921eeb4431188c4c7b79edd293f24c3a1496763936b23d599d922b82663fe59836743d843046d5ac7493a95e36d16b770b7a47bf5b958355fc289c653e4637dda5ea68d40253440eb96f5976ad7a6248a138e760352792267249e91239050d4cf24406a57b2d98025bf104e587632aa7c52f65e781561b0e71c5ce16f371fe50da1f6008f2824828523fd3e2a201050b17a2b474491d49a0b36c8c34eea3adf9339c20a651d6eaa5205f406d933113816e1b5e587ad49a09de8e6e6630f60ed96163833a8560385c1b2124f165ece2ec52af9a9b612f9dc03a81190e5f46eaeda60faa0b7fb79c047207cc4e48078a46a0c49cd1132e9c9a00f85a193551a8cb4b99ec1d6c07491c114969b652935a82bba252326dab5440cca66fe24c37fae468a32b22d21540862f062c148fbda0f0a320ca12ca1ddadc661b19b45c461a38171ad57da96b89c01aba52ce596ebb325a22016e2070d5420284e4a319bf521480181ac4294d28ee037016f03149ad538e632f3c274a162e93b982079fa85aeadabe3cc58671e4bc0a2604243037ae98211789dce0b5a59dd89cfd5b13c56c97d520d73a4c373501f604c3316ce255df320b9494d10d9415faed012ac6b53400bc6d47e3307852697a142c4a9bd28a16b11cf93af3914d31e020ebf4ce8dd41aae69e8885ba641b47352212e69c03f932c5c4d54687a3503288ef5c3d6ab83fcaf2059e9098b59a898c7801683d636e45cbbabd1d8268606c3764111666fc3d57845891126dcd9faa5191a8bdae12466d62cffca274b10129b5d1d5caba36c15bf1e7de911b471a3c7a82ac6ea2374122e2770f8237c0d48e4e25c112b2f6659582567088482c9e9e0789191d226353878202120448980a6b7069bc71bde617452fd2317ed4e989f771032c46ba99724806f5998c8e8fe940b7ea24e6291ea5e550e7e5e2088dcdc6c60dee55496f22c870ca597357d728a9e45c4a8a44c984f48a62281a994098558f77eb70d2b690601a92c8327ea246355744ad97d912ca63d84eab3e0cfa521ce800699989a79269d10fb9285826da751db0dee4c716eeb946b59bf312226e7b95171915ea15615a1bb1c59a749cfb12761edd989e08a79079af4a781dc4f5d6056a91a0661742e5d54673a6c1cec1013739c2e71df299942769ef25da2e5daba26f9addc5155a8608aecbf53254c2d27a588b0823aa54d0bc24a2131b7d842edb3f9666a798f3e86abfe279d86259165bd93e8e7f913ab7d14a94f40cb44062a3d2728e9029ebaa6865be89d7d052c049e7389ca866022c267a3392f689d7ae627fa3b58141ab762d10be4e6d8752edd88cfa3985bfc723023dc380398ee9d9b9b9153a5a06eb295858397fd7719400f80e38aa18fd1eba6c324b15726f4907b84897aa3ff347578a13f1b905a148db1ffe55813c17831f54ab7eb52b44545427a25c17481d0851b590c4e1ea2682139c421108dd2bda3fdbe90549a7548e1463cf0a51e4abe1c171f4866191cba036d270248635c48848fdcb690a0bae3240029cbd688a4d6f150d08d6a0b4e62e2714e57806aad69420c71a72788c996b19b5fd5870506262b878e354056ed2dc4cc6bf00e59acd15ef776d1ee75970799c95a5a32814f8e790d459d32d4ccd807117acf2d2ff290a57342e9b439fbc6163c268953fcc0444d5afd040dc035a3aaa54884c09b4d60f2c0cf2c1e91cb1dd5573e26f3ca8609d3d582c926d429005891c02699e5d3c40eb203a8641fb8bc5dc13a04e832b954cc0003988ab691495e5662e21afb22ba667836bb7f177301005ba3124e4f947f851e5de9b8042b5da3476cbee91e588626da672217be58d146a2f3eb590be8832595455972b5531a87b1e63c20ec19bb9ee925ed1d5c7765b19c199769920d8c4ee6d7eaa3973995011e9e77c6de17662beb49ee169dcda4c6d7091459794277a0418c55926bbbc83a320cc38de4126612a3bd8a55ebfaa897c9e17082319d71b2c964ca7471721e96c69bf84d2ce9149069e119b3f40617d20dc20404dd587aef66972f14369056e2673c5cc54877f69bf8e0ada3527c58c9d8c408ce218c04858e5b94c4ba2e2da592b4c0bfb2c9e0a894e614e7a21baad239149743d1e4b3b068c5c324e1080c09eeca22487b2d807620ff20f64eb1ce404ff82f3926c0673b4341c6a6a1005b08e1fd27578ed1373af6879be3159b2cad27a29eb0c9fab2358258d0a946b1396e6d007995c291cbee1837b4454a13c84aa7b4da799bdebe33b9d2879d11f02008c82a7f9d48c33e5c57a74f731496b62a180db690406a9d8828c13550093aa1a29309ffb96adb68cda1a1089a
InNoiseE = 121aa624d30404040175048b103de50d947082212327e5c6d7208da2728f9ea5ef151880c98011516e525785943af3824676c562531144a82704add92ba0079da53dc88ed59d32822781a41949f60ee8a8b35822bf8bfbd3ffa47b0a6b46a16926ab810de79289c15659261bb4c91600975658b4239a00406233211799177811256b0f7597ab4b169bb0424a900f76759682b3d542d341e60066ceead0b319e40edf5333177f712c4a9788c11d701f2e1a214aa7d87210a1df861de92d676999e4c68e0ddb41de716c0c569c5e8bc62ece83ebc14266c819573edd33f5c52c286d65dccb8a3444d228800b1dee5d88430fba5a708637abfce060c57cb926dda157092959e01b455e754065dfb97092c965b0e861fb7dd150f811e5c3f77d41c7dc5356f0f497c0e7185702398a8dc5d311c58c02d00d18155e1901ff0afdba08724a5883e7b2a66a4dd2d85cab4e2d8c87856cb93af91cac1337c828565d8950fae2582177bb40c3da5e5034e9478b2789d163d720229b7be153d5575c86cfe58129eb1435cd8e4a816e76e94411077d9d9837463884452e5dc8471c71b5c9fdb859d25734295fe0be0c551fa901a6fc4515e7554cd3bdb87bdfd9f17a41a13396d806751c1138e81995ab879d59aa89df001fd882f5138df1bf62ad4d96ef641c3577e04ea5e372ca3a47d7b8c8829d0f9da89c25a394a0921f4eab11ad0e17e931c1ae1e89ff0c59e025bca569823017f9cd007605d156a2ce6ecadba763dba289f6805261b0d23cd8aa9ae759f066c0130e675ec52f0797e278b0eea94a6ca80729459acb40cf19af581184590eb70b8c1566534de4f5dea35c61a9f62fdc307f282fb33d84ad5718459287853f769ce497d25c3fd55192468524293aa906a6b1f11524804375f8b8324d084f639e5506bd55ab5732669df1159c70b3ae32ee63cb06317e645d241c123a787402491c31afed53e0228dc0e2462e86e70b8afcb0065f13fa8193be55a29a59327788518ec8ff3b15d290366bb93698f82c2bc7d0a2e9c50f042708b403982dad02ac976d9aad53a2a8195b6844da8475772ab8a322ae12c7b81ca7401d5942c8763c00c503e6650a95108ab596b1814c4f919213722a4a36d7045b9f801ad9a872b3913e41ea46d01434f9b90ce4b751e01821bcd883a63a2d9837121ba23b2d72bd8a07e22b14bdb3c616a832940100541936aff634965b5c0b9c9051dda6fd7593f43e266e56469c0a90c0ae5e57f781780b111bdbf2c9667542ac025f6697cec7a215cb765016ec07224b4d58f18350b2aa764368a69ec4913a3534c455f9f2c6a10d6172d61c8a950d8fa6f5c6a5b8885de6a227b5a8708d868a51315ab6c61a16e9786e08cf3c857c415662e32ef97b8e24c5166c9821c02f8be965d890d154f01f5eda8136713607740a122eb26c0910040ae879bc935798da8413538e2ea9568ebdc9504c202f9a8e79098ce92e1e6115c507a06ebc055e64094711c5388695b84858989cc2eb96900a48129198324af985281ce6ea74d0c2a4dd6515a23bf488808344f00f3023905de32185a915fddd9901c0f5724eadc850439e2de4e166a5814c3e40d36686c5115ed5c13d7146c1031182e3175de04cdb54add2ac990600878f858ee4970a89286ab7e04587cfd879a8ca8e2a2dfef6ec088090dd20e0d2624ce5edb6f57f46aed3ec8039196e9c7bcd353acde58e65c26b01a6dc7f03eb1de5c97d8c9c97cf9b5062341800e7fbe0de48686645b79c257feed2253a1ae5a29ea0ba1479da61130159b8494663f56d465b91026cb7ee7a56867688575c0268f0ad053151716b37a9b9dd6fc4e6738132f4e4dbab3ad61ca24bbe49897958bba0d0db6276100c2fce04e04e392cecdd6799126f8f179494f1563eca6a2c930acd95f169b4308e1e62689c14b8e3f27be3c1a772948a77e4d38990a9983a744400bb0aec769b21db0ae10963d80e65619a7a39eb6bf614b64811bc452f67a60d595c6230c802f252cbdc008afb351cc4268137f48031d32ac71b997d9f6eda00f5efe28078a31bc2ca0e77304191f6d7aab3e561a7577aa218a18eba60257a8bddeabdc61164a8111886d89000478f9c1bd005198e5be5ed27078e096fd56030c51c04cc673f09055d3de26119834e668192d045a03cbe054768d05be3a8895205e4713a8e826bdbd6660bac715125f928839981ee898fb4e89d196b213f38643a3b9008d9c8cf4a2f5d43e232d70582c9e9c0767d64068ea447256d9e1ddf9e0e3b831a702acda0d110b522ef157ce9674d119ca14dcaec20371301c89263e42f57d15999165d0f44d11a54564a083059f5633cb9bc4e825f6bef346985ee571b8f1c45ec8a42b9cbf4abf214ce904e4d5e41636f57243a0e7ba4a52aff900cc25eda444e814c9f253fe34532a198dcab228ba12f2b576784f7847a8596fce7caae95eaaba06b74b67c90def7db4fc10d645b28d3bcb40c0606cdbb63a48284405053da8d2d67d68bd3b1aa0a
OutPK = 9b9c71049e319792e1110bea4da03eda4dd5220d01ddc3c921022e5d3bcf8b70c1218b77d576d564c08f95d6fb271fd09c6c546e764e2d8b36a72e852de90d89683e9b54598fd7dff269431685381ff842643813944c2d502a582162ab35125938acde5ea3b2644c16dfca13360efd8c0dc02284750c8e8255aba28d2411591463186d4c5b63caf21a9972560c848c01d650b256a0b2f312850de681720a35012ad22a1fcb89d491768f9524e74453370075d5a60d6e470cc348f1e20afcddb41bf44c73428f41dbc50e27248f7f11683e0abf5e1bc4e1e1255fe2b22b1bec643389d453a8e58be11205237d8e9578ca9b822c18856f6e2434d39286dfcf2b6280d84f6ee2e1c3fc007394240e448a8429bdac9dd659edab45adc3608b1050c7c521aa19e056599b8c820e740f22dc6e15b520a8f4933f53adec2e9d270100389991eb00f6f6f21676699d72f95ae838dda9f5e43bfc985c554532801122e86527aa690c4567af3eb755f540abc6abf744ce8ae69f83111a4c9a618373c5cbb61ab2a91b028338b1242e7f170196331e0883c66f784c6edbbe8b0aad15572a9116fb3d50759a3695e38d4ae7c61888a15e056ec2057269f5600424256435bc2321ea102a333531a96ddda6584dbd3d171109b2b533d00720754d99b4d7ceecf891823b2a95be9bbf960a2626281b7402a1555ad5933c793757abc611e9ae555e882257a4125882438134c89d17948cdd4174a28178cb0242a55571dcaab8cae3494578ab84124ace3edf82645ac1386c12595debb108951e4d32567fda2e12cdadd810ea61166dc2a83e6d9c4a578c212df229cd0b8ae52e89584b2729359f912a6e6fde14b1e22a78191bb26259912be8ef71edd98d85484e647461ba9c5ac332d8959a42c5088990ba08cc877b0acfc964b31de2e8411a5cd6d94f769c605c8a5a2b25c2e66f42983281e41143c489ce29887e1f7898a4606071bee156bef0d49a455b21f5ca7beaab014fe597ef3d9d514d56110d21b532a5f0401419663d215b81ef7d7f28df3f1b2d401df4d8659381ed4ff8db80e964aa1b7297f0632d2c8b2b822678e1b861ffa9bdb03e013e916a392895c91e890c60d65c3650b1cb8d4adbd014f45ef50617b48a2353db272160a8d48728c2565c6a0511b934a3050a246a200b6e296d694c324376a9569f0df0c525d24ccd9b1a779da422591cefb952dc72f16859a1e6b84db768233b03581853ec7a40bbf98980411ebb5a396352d492b6accc79129b964417e94871c480a08e867c2069d5e03b994084e4c5f3d8c499054c2903d1c0913864b92734008bc396448340b91c5157c325e1a107774dc1779352164508fc721d268393442c7212e8a9da833c851b224ce7975e621dad0a191575571e6d505b91c7423884bb9a464a64e6a40e566a70c8c74940768fca4b62d03023c430826005b7bf9dc6f863f51e98aa713b781d8aa1aa65f73de019be459852850684f963502a82c9619867026064f9543a13dd7af9bd77eeeb25d2566cb2326b2d50805602dc270655d8eca27320d5302bca56ef5eccd4046066a4d9778675e15a01d17363d0c5076f43de1084f551674a6b02a990ae164284e467dc300b5c619bc0a45e411b8e5b15121d1e62668850d4a45ec7a56113e213dd291a40d80d33be8c0cc3fdee08e0a94182b63c4d8de78c1aabd5ab6cd90b18de9e7e5684f8b497a1751867af4218c20ca949fc8506a837fe9e1843b4da6dd690c9cab2e00880089bf0af4914c1ab01241c5e9816efe9275138230327e23a6ef42ce810c088feaa8b2a5d120837bca64b54a57618228b5bad1c02d33591d71790027780113804dc60757991c1150580398a45c1620bb17c620db8ec78d04770b2295086a6a6ea36ab0f44e13f70364a890532f08a8f9a11557093a27ab8ebd5a0bc9dba17a972c4db39aa6580c6b1a4a1208e5af6cb6d246ec44fb463cae807f668eb27c3390a60ad3cb3ca021e06d295ba7bf07483076f73ba44ba81609259aa0d7b48a975b56aad075c06002696da667bd23ccb26045bfadb6121dd810ea05b77195dc66cc5c68de68df80cdd2ea6a699c451c2d6d033c6c4915c8408009494029fa3782442f83d0fa2e8ea536d1a8f4f146344a639609753810a512539eed3673fb60ce58dc07b97d80369021f6738c92ea445c038e0cc89d8596e6268641b2604b3a6635d594b9348e73a6a448840623966fc5497d1cb252714b993ef45a27b3d36f01da8cbface615dc349b0d8d168b1aed283bd38302fc181984734231660e076f7dd56eaa839f398d18c00cf4a418961231a506ec185b862d4c442b2820053831abcb609e13956d9440150e50da9850f95ea8a93bf54984b0c000bc299a721a35ab9882e5c9b7da11265cc36115071a6381145b22246a0d3e851d2d901b79b1b7bb2b8d659bd5b9aeb9288582b69b124e189a914a9645056603db6649cd5ace453c80fbd592a06779567e41532ac0318cf3eb8d3fa154d6197216326aa
InPK = 9b9c71049e319792e1110bea4da03eda4dd5220d01ddc3c921022e5d3bcf8b70c1218b77d576d564c08f95d6fb271fd09c6c546e764e2d8b36a72e852de90d89683e9b54598fd7dff269431685381ff842643813944c2d502a582162ab35125938acde5ea3b2644c16dfca13360efd8c0dc02284750c8e8255aba28d2411591463186d4c5b63caf21a9972560c848c01d650b256a0b2f312850de681720a35012ad22a1fcb89d491768f9524e74453370075d5a60d6e470cc348f1e20afcddb41bf44c73428f41dbc50e27248f7f11683e0abf5e1bc4e1e1255fe2b22b1bec643389d453a8e58be11205237d8e9578ca9b822c18856f6e2434d39286dfcf2b6280d84f6ee2e1c3fc007394240e448a8429bdac9dd659edab45adc3608b1050c7c521aa19e056599b8c820e740f22dc6e15b520a8f4933f53adec2e9d270100389991eb00f6f6f21676699d72f95ae838dda9f5e43bfc985c554532801122e86527aa690c4567af3eb755f540abc6abf744ce8ae69f83111a4c9a618373c5cbb61ab2a91b028338b1242e7f170196331e0883c66f784c6edbbe8b0aad15572a9116fb3d50759a3695e38d4ae7c61888a15e056ec2057269f5600424256435bc2321ea102a333531a96ddda6584dbd3d171109b2b533d00720754d99b4d7ceecf891823b2a95be9bbf960a2626281b7402a1555ad5933c793757abc611e9ae555e882257a4125882438134c89d17948cdd4174a28178cb0242a55571dcaab8cae3494578ab84124ace3edf82645ac1386c12595debb108951e4d32567fda2e12cdadd810ea61166dc2a83e6d9c4a578c212df229cd0b8ae52e89584b2729359f912a6e6fde14b1e22a78191bb26259912be8ef71edd98d85484e647461ba9c5ac332d8959a42c5088990ba08cc877b0acfc964b31de2e8411a5cd6d94f769c605c8a5a2b25c2e66f42983281e41143c489ce29887e1f7898a4606071bee156bef0d49a455b21f5ca7beaab014fe597ef3d9d514d56110d21b532a5f0401419663d215b81ef7d7f28df3f1b2d401df4d8659381ed4ff8db80e964aa1b7297f0632d2c8b2b822678e1b861ffa9bdb03e013e916a392895c91e890c60d65c3650b1cb8d4adbd014f45ef50617b48a2353db272160a8d48728c2565c6a0511b934a3050a246a200b6e296d694c324376a9569f0df0c525d24ccd9b1a779da422591cefb952dc72f16859a1e6b84db768233b03581853ec7a40bbf98980411ebb5a396352d492b6accc79129b964417e94871c480a08e867c2069d5e03b994084e4c5f3d8c499054c2903d1c0913864b92734008bc396448340b91c5157c325e1a107774dc1779352164508fc721d268393442c7212e8a9da833c851b224ce7975e621dad0a191575571e6d505b91c7423884bb9a464a64e6a40e566a70c8c74940768fca4b62d03023c430826005b7bf9dc6f863f51e98aa713b781d8aa1aa65f73de019be459852850684f963502a82c9619867026064f9543a13dd7af9bd77eeeb25d2566cb2326b2d50805602dc270655d8eca27320d5302bca56ef5eccd4046066a4d9778675e15a01d17363d0c5076f43de1084f551674a6b02a990ae164284e467dc300b5c619bc0a45e411b8e5b15121d1e62668850d4a45ec7a56113e213dd291a40d80d33be8c0cc3fdee08e0a94182b63c4d8de78c1aabd5ab6cd90b18de9e7e5684f8b497a1751867af4218c20ca949fc8506a837fe9e1843b4da6dd690c9cab2e00880089bf0af4914c1ab01241c5e9816efe9275138230327e23a6ef42ce810c088feaa8b2a5d120837bca64b54a57618228b5bad1c02d33591d71790027780113804dc60757991c1150580398a45c1620bb17c620db8ec78d04770b2295086a6a6ea36ab0f44e13f70364a890532f08a8f9a11557093a27ab8ebd5a0bc9dba17a972c4db39aa6580c6b1a4a1208e5af6cb6d246ec44fb463cae807f668eb27c3390a60ad3cb3ca021e06d295ba7bf07483076f73ba44ba81609259aa0d7b48a975b56aad075c06002696da667bd23ccb26045bfadb6121dd810ea05b77195dc66cc5c68de68df80cdd2ea6a699c451c2d6d033c6c4915c8408009494029fa3782442f83d0fa2e8ea536d1a8f4f146344a639609753810a512539eed3673fb60ce58dc07b97d80369021f6738c92ea445c038e0cc89d8596e6268641b2604b3a6635d594b9348e73a6a448840623966fc5497d1cb252714b993ef45a27b3d36f01da8cbface615dc349b0d8d168b1aed283bd38302fc181984734231660e076f7dd56eaa839f398d18c00cf4a418961231a506ec185b862d4c442b2820053831abcb609e13956d9440150e50da9850f95ea8a93bf54984b0c000bc299a721a35ab9882e5c9b7da11265cc36115071a6381145b22246a0d3e851d2d901b79b1b7bb2b8d659bd5b9aeb9288582b69b124e189a914a9645056603db6649cd5ace453c80fbd592a06779567e41532ac0318cf3eb8d3fa154d6197216326aa
InA = 466e66f041312a755f555a949a661f8966f440cc2d3a4cfc08ad7aa8f018a681444247d0dd37b2ea61a2496ad9880bdda2c2c41895f83180f79cda5ba1f202f19896aa9ba51443ab58f7349c1fdecef93b444a9996a13d716e709efd1c08e2e2768daf974c78dce6a18b5eb9ba8db402ad955609740425aa21457adfe5802991075b62dd62ee55135b4040a3b32147748e9980e0958736c66c24262cbf55c782646c255712e4665ff80576774d420f4e13892016e6530001df93fab40ed9d48ec5d2d44726cfd0dab47094b8dbf0da6da5b4f7534e680166788daeb2a7bbfa2f746fbab1346d3f3d8f82d859f973661c3c6bb624bc0ed2de274789275110fe50b9e18ca5196040006e9dc78be2bbf1214e6e47e305f54e7d1b51450781123ae01ba6774ca51a7745f2a68aa44e37a8d6444fc03aca490fd4a1aa02908a51e1df4cbc1d0804d70f9d94859b01264cea842da37d86fdf97f5cad10b03aee627545aa02c3d67f07de5f63624e45615308a8e81d55698851ba625188624b032aa52cbbda9c80f715897fc86d300b527d303aeb03b8b18440b21e2b0a682da5740dc9c6863a5a1606ba784e2e47a4ca2fb09bbe641346d533e82c221d6fbbd29a2cba99d71fc153959c62985bb092de06c2253a032ecea0f6d8bb041ac2236a98f51a7220a73c52f4498d153ad99774883f85680410944030fe28204db6ba2a454a0928b10af2b920b3658e92c3bdbcf4681c7993f2aea59c419a979687a3ac2180f94c8e50c293b627c0216f5c0ffa2c310b7d49ccbafa14875e8a94b3ef1e3ad7926db6eafa0e87cf04a8f5101a8407f0d7e731ae31ee23f14c09609c29e254dc781588648e89abe662fc5a79e30cd8559bae7db123b96f4dd878526374311b681c45ddad6d96a520a13d6860e967e3f7daa8718f86f5c4cca4309f5caa4646b2ab5787033553b4149de6d63aa4593a70e6486b0c3d4d02dce897d0e14bfa6bca6b261176ead285e7007905672a76754c8d66414d99781eca5f9e83fe7bc3066c139eb909d3156d79d1860a2650149683e34578f272bd185a93b0418e50844fc04b253504e8e2f7a60a50c1ddeb747c357f249164d437e0bf53a8df2a01a836fa69d85893ea895c449fcb7e6d7c9f24565848b97f529e376885a219640774898a96aaf7c1260b871246949f6874c23e28e2adc98b3d6e4fdf8fc091a45e75ae6503f535f4b1ec20f66b61152f63dd8e3bc512305a0cfe9bd09a5c65910586123a246cd8188764c5895d278ba01f91196f4c68599cf1b3b800c37bd3f813a5ce326b0d9952ac4b6b96bf2468de4837157451177dab8ccb5d90591f5c81f5d8f14855a22ca4e89522fb4ff333756021f4c3b5245738293d8c81d4b0dc7ed618ac14c712350ed97d1685388ec2e14317a2295710418889fc3e214d2d225869509b068ca5032af80db7587b759b4c073069a4c4fe9a8be40f39d500667dc720b90a2ee17785644a6a3be55f51260736ad6525d7e121f413165bb38142621191b7f21feddbb8a658cd013187b246051ccc0cf952f574148317571a6643666d9fdbd4fd7ed343519b791c131c68ee85850595339c962335351744db3738569cb5bd42becb2e3c0c2be214592d1aa3f1d3cefb6b364896cb12096b2491df4381d50ace9f766cf140fb289a5b6415f0fa72548ba6e54a5da261bd2606150ff6003c87af1a687512645cfcd2cb555962d59c5affec340c9460218541228c99df057601824715f38ba0a27f945125fa1322a02c4b0e3388866cb349f4d0a1e423cf20d41055a46be20e0a43d70183de531537c9ec0229a65168027494f19a4ce8ace666298bdbe3db10bafb4661d7c9f8b70ca955d7054a25dbcc6575a18979ce4d42118039a739811429d0e26f4f6b842890e47c6d5178d5f2ccac590157f9b35aa0746b9c9353181a546ecfc92131ba556c1638a9529c6688f037ebf8879e15ebaae9f881c9db1143d7509b2b8ca242ecd245dc0898f847b96bdc4c273908a2149817eb2bb0aa9963e54007767ea0afc0d9508f0e5039cfa257f19cb57898c52737f16958e30101d289a484e7e460643409126c6610a15570648a40a0233cbdf863cd1384299f6cd5b8a88c700bff8faf80bf35874a024db6164195bde038e2f61c4d9e6994643ef0923f6c795a8f2a9d24a2bc391b4046b8cf4bfb40287893254c493a70434b12af36c64d645ccd6e4bd8c003674bf315e512bc9d21b6121ad11a790197bbf5b453f8443449012544e02c5045705c908a89f2d1faf0309d0aae891efc1717aa3f32ce3645138c13125db68d06effa6436359783c4d863702e6b2b4f7eea76a4504a8d01d39ab252d66a64f3b19186fc5918f19d4a36d2415aa943d267cb5d4673990e74fb8ed8484af02df782cd23e302574069aba1a631959be32831c3a27b35a3ff909de8a1fb2a6c852fd05affdff5fa11ce353ba7a3b1e1920bb62c497acdea0243431d8ae65459e867aa8082d44a5ac8fee3bd3d1653dcd0d209a62c
InNoiseSP = 6b8addd536524101c8fa265801addd950fd2d7b19fe4a590e175300c2ce7532a467165019fd7d1485a779105b51720b68eccc12c95622861c18d5f3679a2a11466ef66aa258e61cd0f26b2eda7f1400703868030296c41c241cc5fa7aac5212c6e52a8c20013d9017ab951af7513c82d1f8531abb4214cfcd5cd72377563db181ab084f6afca162a866a941a899cad20cc1156078a71c6f6f8662e6424f87b8e84aee1ce925bf273969256645e648ff6286677915257c2d49210a1b04e7b29eaf030ca2dcf8c0d3375096d41a904c36b2d1e9e466c73d319ba3cdd79b8081e1d7c6ee100ce0e7a40496be1f70e338edd9aa2e1ec869c859f1817456ee14fa8118f7832f50ae0e5a73a8964527d421b76678fe346d8f31511576e2c84ea6415d1061ec46455017fe70910d36c76cd131f272ba180ba12a3cb23ae6079892c058a8a0d01a54b398579b1ecc6a1f3960092d114343027695b87eff62bd35691251b935ab332aa00068a89fcf25b14d6e9084044959d830d686fb92ba222d7bb712c0572c8fb99eb4285fec5dbe5d7b83f8582c49928d65466c479831d116482cae805037ebc2200fbdb1519555c125db380ecb068df5efbd33a7df5c257462c3215ae29bf316d72bc7c4834a55332995ec99882efd9666be73afa6f8e0a3f877e9290a89bfe47110284b8299727c05a38b20807a93d17e4c55595e8a392deb58cdc568796b9f6bfd0d34b3af9318ff9955da956b5a555a023f6a68455a794e6d3c86a6c46a70591e598074eebfc87f348bdbb2b21399b3d35b360d429f341238d4ce695a8699f4c6a41a6d865a9475879a1fd9a0ae62808ab242920bcc8011611dc677aa938564b38b3911ae2721f02aa9e8701b686ac17984190ea11ecbd090e2a4b4f11821daf62f570150ba8ee08e0493e33fa0b108a9ba2a897859cc94a6545c34329462df93f84c3b35923cc0fac9442025cb028fc9519b70dde566d2c3f2899690cbf4b6656e979571fd0aa5af21123c753f1d4a4fc24db4ea19623ec2ae5cfb428d9a054c00eb53068bd37baaac8eb18723917ad7737e819a189928e8149ec83f7da1807fb21b5a644c3b4c77479529e4cd112451384275d869be843ce9479723d8a074cc66be5054197b9e0fcb0c2260e7219ce86c79e0f4ecac526ff5a716059e4a9a1f6501bacbf905a3c99af11e7e242de820b82795407da6ab558bbc4d5567e44d24bb8561557f49a675357893dc8d5e873dec55b62dc0fc77bd469274cc425c1a174c54ad6e6f649b38a8b6749101623bb5b2e38d1eaac041ccefa6c1569adca16843b059fc35f9ac600ca1a911940ab15de9c4c144a21e6e452899c9ee173113fdc2d90950ce26d38827c21c83c1e63e61a7a3d3a06e8171660467595b1671829ac485503164894bcf240d2a05576f20a78869a7899ab682c5fcdd067da91a099a64266ea34a513666e89a292bf1fac7ea8377e5b51e398e48ec92622597d03c4054cc94593175a28a1f981990509eabef568e4e65e99437a2b8291a2c60a6f69cfe8c82aad1759fafb716d63675040859821ab1c9be1b36c2265ac80360afa196e22c4a1d945585f4e2996b4e91866cc28ab21555954844d9e714d96a6145778a9e6603abd4ca802778ea5748a4799b7faa04345eff917ca729dd1a1e5bf88b8ddaa7a33aafa6e5eec53c7173222d4ea96a1446a512b6e12564c0048df48fb88549a37d2065904cf88b3804cc20136f98aa69cbca686115f9daed1a622746ee9993fea934ab3d991e2b2081202085e3ff568a098a39e81145a7a15bc48c26a47ae28f0691f33fcf8515345ebe88a09656544f3a17f5d41dfa4926815ecbc10424a9219e62a83584382fa38bdb00623ba0f20379691e17479fc8ebd12607bf3e4adf559e51a1a1d8788d32269187532c29982899e5a83b7c6d929584c91dc5769fa5b1489499b4fc4d5a479ce12d4b4b2067628c37205d19d00874d3181a0981718816202f6ad6c8de8fcdbe270a30bc6f1899c2e8886a1cecbf68e2542a7040abf2c0540a9f823997db447149503f4764706615db6655c0978e31dab5b256995a08f7110086602ac6f204b55799bc8f68616010c86c4a090cbc55b1385f3d231aab8988ee810249c4dc82bb1a96485afd3093976b54588b145a3e4f426bb80c32da5d7099100c54df1360d8001cee5b9d89c19d501fd6b9e7596b20969330a117b5c2d492950841acfec61e20bd8b55222389624716fe859aa2bd21043082b0b8be3991bf7cf8843f4322a6e167b24941e7ede5b5d0442c166d6a00a745d1c8cbcaa56889fccabe0ec2048cf6d30a98e64c5e152676f04b6b50d85ba068ef0c2a148731b0132f50f6e869022c446bad8ac219fb3c96e754092e6b7f64e608bfd0e72e7015dbb3c1f210254745e135bbfe8c46488a05065f7d97a90b61bfe24232aac498494f0f89d1e0293ecc78fec02c78c30a636bcaeb86de704b10cb411292b84027c1ff3460016b4cca36c6bb2fb32e040050b5c368082b9
InNoiseEP = 3bc5cf207e017b682a21a47b75503aef0fe96bf80d73a0cbe9daf58eabed30e0c9d0a1fa88bb7a42761bb598d4c37bb61386a63344aa8c42a39b13cb87d902a112e264c4fc286e6703a6cf506e8fea14a1b4a4a03ae998b995909d2fca5196d80c176b1a3f351e3d7a56d08f8a235daf03c80a9501c08756ebf040190eb76e8d740223a43f2853f251432825485f97497090b3b9d7191925a28a70d32646b1486743cea5d364c248d3e474e27e8c173218428af32eb5780c4ff9c47c2c455d0b83f01089b3652cb921560f7c646c27e670a359537731cd9e149323df20c199b40b66c06642a256d016b4c56cba3de19be9853a30a39b2959cb215d2eac56d5d4dfb06a4f82da34cf108804d754587ab450f06327b2cd88550feadabb8e9d1404526cf74ea4125a5eb5c790ca16594739d54e946779abb3012689b6066aa2fb7d925b9893e1f067d5512190a349785c58db4c9fd265148d3344f5c1b3aa18928899b33aee55050451fb167811ae8a5c50b9f40400a4c28bba64096f088af54fe4885197b814c2be2dead7c2e7f335916aefd94297b89a384451b7dba87b01cbbc36c37c9bb09661a4f8389043253331e2cd6a41c948d6309284579dbb3648e86f9cde470b8400089a966888663117e9dc21580889bbe9ca2517bdb9b58d5740f0c16a8dbee0a3b1569c8d219808a9a7289b94268a23f1c958d2652877172d917da3d305757d098986f6e2e1e460a3cf4b0094d8a050e998a6b4885ad106f0c98b102b58c5c4b63b5e1d442974bad2f06c9feb0d01219e652e90db2338fe4b4041b665668c5a00a24530b3a181d2089bb6a4b599d2294d2036562f5047d8938715213f90630a58014e174f906ad0a20821a539775efda2b4e25abb4fd0090ddac2774db411ee4d43339c081aba8f62f0e291351b1fb84a3e28191714bf94b3a94aa529eac8b0aab51945d185ffacb823e163b379fda4de57d23046618180e0728367b262ed6da3629fd91e2baf7cb9d4d401d219221527da00a0a0c778621aa7bfa73a2677dc10ec81a1db301884b86e5b0ba0928e4d29e10b11243fd39990a25a416d3ea6d214620645969be0e634544df6c48e1643964e68a338d5633e4b085f2f36d234959b69b309f2f20015dbf9f71bda678b85f186d75999ec1c3da0b6128f1304976b381c3f2c118312af521b0f810ac1d190876c5499aa1e0a0c5e8b9d7975c92d31014177bb310c2a282be0740297629c54f5d1ae79361cc77650c0a6206fca4441a52e780bc22b71dd1dd12f4f5886449a1702cdf04c114c628e0d7975110e85cf045bb820bafa99432033de0408e1b81a12ee4f8a6f043a1d115d145d729b15e63db3d4e5926f76bca550785be6ca3e7b640f77e82c145e8b9717f2b61ba223248202b68772c9de72fdaa4bbcdf4ac433187a85ec03f8588530dfdd3bbbe5a0490294c5900f8080ba647bf3b8c0a6b624da805f4ab6f04981d550f29219eba6051058ba1a87e80839a572f76320a31731002184843259f656904f5dfae05c91c8df4350f425bde08b2b2651feb012df0ae777c842a44103db2c861b45658fe1413c256ae47ba944ca2f139338c44fa80e59445b88cf6156bfed02166df2b3970fa2daf1c9832de4f5a3b3b199108a0d2af2d237751e868a234a5ac36f8959cbda135e63ac98a91884ca6c62c9930507559a7d51ab52bf3da1a95b545cadc34afe4b1add66fe24b531380811a31d9716972c2e2e261b805c0a1ac70d956720902eec010c78c6bab20a2936522f75bb5dc361f494e289ef5ad6c8964d6dc8e883a1b0e036920a5e011c8416e881de84b809854ca0ec128681ba989db383a1827bdf8c61d997196ff8809f68c651aa6c27f0b825ea227ccd9972efc8a79d80a4a5fa0a23f9035298703208be84b5463a703356a7039563c627841786d0417579e69f495510fa6d6ba2e6e5d5de05de899f53d3f9256ce94079722c6d9bd16d220a3e6d399bff03088e38e3db2ac9d8f44fe426d3f5968539392845cbe00d8f6452d5f1c87d9a4745391338127996d52e49b809354fde1bf189297865aa2d712f80ac4ecdfde7c58d51e89cea5bd36690276b056b4569257ea78acbde485924026ed86d741356ad5c575aaa6200a5e18b81cd99332723133dc5a00595cd9a7cce957164b3e6adaca3f6ea7d687e444ef39269e65ec81320c5cd283fa250bf4bc246e5595600568440f73a0ca8a30da4e6ac8af4ccd0705ac62f3865f676ddcd9a85c38757f628bf0655ebfb941897fc62e5007bd145fd66fd78b5ad4bcd1392b826554f0a2c1702b45865fde2e1e7f4fe0f4355cbb20b4a16dd9fc0e88e7c57eaa8a7d56d21b89ee79edad6e82b950066f9c06050689b4505e396530c05940a92cc87d79531169c566960802de5b278168563d05908061df9dcbd31268e4429e008eb9e3a4628a194023d1412334975b4ac35a1e4ebf6197e6150b60ca4370a2e3fa9c897554e5a9fa3cfa5a647695c6ca865e402bc5536c2bd65e9112a
InNoiseEPP = 00f0003000f4bf0100fffbff0600ff2f003c000000fbaf00d0ff02000440003000fcbf034002000008000180ff2b000400000000ecfffebffd2fffcbff0200048001000000c0fdaf00b0fffabffd2f00dcff02c0020001e0ff0a00010000fcfffebf0040ff0b0000000400003000fcbf0280004000f8bffcef011000fcbf0000000000fbbfff2f00d0ff060000f0ffebff02c000c0ff0b00000002800000001c00034000a0ff0a000100005c00fcbf01c0000000ebbf01c00000000800ffafffcbff02c0010000f0ff02c002c0ff0b00f4bf0480010000fbbf0200001000fcbf020001e0ff12000200000c00ffbf01c0ff2b00f8bf010000c0ffe6bf007000f0fff2bfff6ffe0b00fcbf00700000000b000280ff2b00100002400000000700fcafffebffeabf03400000000c000030002c001400fa2f000c00f4bf04c0ffebff0600fdefff0b0007000540ff4b00f8bf034000000003c00080fefbff020000f00000000700004001f0ff0600fd6f00300000c0fd6f010000ffbf038000000000c0feafff0b0008000030005000fcbf02000000001300fe2f0000000b00040000d0ff0e00014001100008000000ff2b00f4bf0280ff3b00000002000000000400ff6f002000000001c0ff0b0004000200000c0018000300000000f7bf044000c0ff0a00f9ef00f0ff020000c0ffebfffebfffaf000000f3bfff6f00600000000030001c00f0bf0100000c00f4bffb6f0000000b0002c0ffcbff0e000070ffbbff060000f0ff3b0000c0003000000007000240ffebff120005400000000b00fcef000000ffbf01400000000000fe6f000000130001c000f0fff2bf0100001000f8bffc6fff2b00f0bfffefff0b000400ff6f01400000000030000c00fcbf03c0ff0b00f8bfffef003000f4bf000000f0fff6bf0300000000f4bfffefffbbfffebf000001e0ff1e00fd2f000000f8bf0280fffbff060000f000f0fffebf0280003000f4bf01400000000400fd2f00f0fff2bf03c0ff0b000000000000200004000140ff0b00100001400020000400008000d0ff02c002c0ff1b000400f96fff0b0013000180000000fcbffcef002000080004c0ff0b0003c0fe2f000c0008000680ff3b00fcbf0200feabff0e00fc6f00000003c0faef001000040002c0fe0b000f000340000000fcbf03c000f0ff0600014000e0ff0a000240ff0b000b000200003000fcbffd6f00f0fffabf00b000e0ff12000000ffebfff6bf0140000000fbbf003000acff0a0000400060001400020000f0ff160001c0fffbff02c0fcaf0000000b00003000fcfffebffbefff2b0000c0020000f0fff2bf0480ff0b0000c00100000000030002c0fffbff0e000080000000040000b000100000c000c0ffebff06000380ffebff02c00030ff1b000400008000500000c000c000e0ff0e00f96f01d0ff0a00010000e0ff0e00018000f0ff0200040000000007000180ff0b0000c0ff2f0110001c00f9afff0b000c00010000ecfffebf03c000f0ff02c0ff2f00000007000280ff0b000800003000d0fffabf0480ff1b00f0bfffafff1b00fcbf008000b0ff0e0000c0ff0b0007000070ff1b00fcbf0000001c00ecbf0300ff4b0004000070000000fbbf0240003000f8bf0000000c001c0000c0ff0b00fcbf0640ff0b000c00feef00f0ff1a0004c0ffebff0e000070ff0b0004000240000000070000300010000400fceffffbff0600030000dcff0200054001f0ffeebf0280fe2b00fcbf0680001000f4bf004000e0ff02c004c0ff0b0000000300002000f0bffcaf00f0fff6bf050000f0fff6bf0200fffbfff2bf03000000001b000070000000fbbffeeffe4b000400038001d0ff22000000005c001400003000d0fffabf00f000f0ff0a00020000ecfffabf010000f0ffeebf01400120000800ff6f00100014000180fffbff02c000300010000400fdafff2b000000fe2f00ecff0200feaf0020000c000000003c001800003000200000c001400040000800fcef0020000000000000e0ff02000100ffdbfffabfff2f000000fbbf03c0010000fbbf0200013000fcbf020002f0fff6bf0580001000fcbffd2f00bcff160000c000400010000180fffbff0e00ff2f015000fcbf00c0fd2b00f0bffeefffbbfffebf0070ff3b0000000030004c000000fcef004000ecbf00b00000000400038000a0fff6bffcafffdbff1200feaf002000080003000050000c00fe6fff4b0018000180ff4b00080001c000000004000180ffcbff0a000070001000080002800000000700fc2fffcbff0a00fd2f00f0ff06000380000000fcbf0070005000ecbffe2f00dcff1600003000f0ff02c0054000200000c00500000c000b00020000dcff02000300000000000000c000500004000300004c0000c0feaf00100008000540ff1b00f4bf00c0ff2b000c00020001f0fff6bf010001100010000030fefbfffabf00b000f0ff02c003c0ff1b00fcbf00800090ff06000000001c0000c0028000f0ff1600
InRand = d7e1e1191de63a93fd94e7106466467856449206e281c17eddfe5597c5ba7e7f
OutPK = 73ae7fcb7366049e5c2060340422d555213529f573740c28c3f7e11191d2ff660c2c9789d31cc5cfc91227e48ec3c9593df0524f9998904f8d04d3a82de231ac4760a3097911c216159909a08c42195a7661ee825a93108560d582792bb5566f900ff301118ae6607d8282bfc340de1ea6463cab4734ad43e15dea831c599fea681947790c8b1ae4f24ed2460b68d371b24c80474ce5a551418bfed86f0349695f6adf26da3e9a65d3913e29f96eb9ad94452847d43b0aae7401d46aa384108de8ef5a906299744b19ed4f62ae99a6bd18580b6d736ac04a5c450901b8c61843470c23d37b964a200863097bce54f9588db1ca487107eed30630b013774770f881e9375e99ab44a978663d1a22b0bc3e38e19e4f1042e07fb8c3340873b60def9f9cd605eeaae4609742139517ce5f4080ca3a2e6b189b4bd26a6700d6bb7bac648774962aa27ec4a9c5c89c9b264d0757497b88825859cfa682db002a9665864b5a1d9154456a1872321e6f596b87a810aa3cc326070a06be443d5894e981bc4552abf2faadbc37a356f8e5f0655847a6d7aa8e8dad54442ce0154546f784609855b677986523c111b54221dc88e7a2519500da5cc2e9b0ab31db066aff6e3c1de5de84f8893ac361f494130943c724dd563070a23c0f7601ee0077f46b38033f2d493d29c27062953d7594f5c2381e5500ed684550b40959ce1a8327b474288e0fb052a0466a11239574f9ad38467541aa1276cee8aee57b3ea1f20d8cb40f74925415e8099c896e6fcefbd8574a47496028db135433d888690a701118bec07ed04150956586ef56a4321aa18a5197553aa37d1ab9a8d4905f4ece940b7442447f21048b562e75e490e46313a21866ae6be3951e3b9d8c56c940a46746d18b285e1c5409e5c6007b8214d8976e101c161e1e9aef577614b08b1db9d4ebcc2c568598e5d35a45394233254a651dd543db9081ee320207e173732e3c3f19707a0db288e2635029be6e7266d37332994c52e3d445573aa088abcb5faaa5de1dc801112649ed8f4e95190091e00482024a96d96e1a0b14d7c3374c2df96689e53409239f03d9e576c9a3da4725d4dbc58aab1f36a4ce346102923a9052f95703ece5208e9cb6580c9006fab2520549ec5ad3ea5ffdd7eca486a016cea353e89918a8aaee98fab66493c5e8ebb6e7b90da7ef7a812ea497541065098b265200ec25c6d4ba175b6b26e3b03c550668bed246ba5d178f260693858897969608116250652146d3819a5535efc598ab217ea94587042c15711590b3c0e746286a8c521806d99329a8f424c9046336578e85ab3e17ab40657a86b6b4dae8de63bb0573280417c7dfda172320613122592ed64572d38d94864884642553190af01aaf4a5439499883ded55a7a2e3e6b7fa06e909b225e48513cc82fcbdb9c497cba02c06eacc707d5b4825ffad9ca16589fe2c7a365de96b7e2d1a3b7a54ccad5f0f0777834a41ef870ae4560158d35e7e12902b26325d5e52d3efdca6290e3b601f581454236c89d1d9ba978760eaa1018fef4482a6111eb871024d81429915ce552852bfb561ed55bf14eae24ddbaa024935aad9523dc8e7b5dc72b933404ae6dcfd97a8cfe27865774966d74b8cf53df557f8d9b8203fc3824dd44658c23e3e39da6d0c9d007960469768352c42a6d8e34940d93582559494ef581b7b2a45c294de684718ea09009aa1778925818d86b0ee8a76bee470246e480b76716497aac21a9173d1657488a24ac57824174372e89e8f369586ee4545a06c2f960ccab7e21237d9b0a44243082201c57d7e69be972b5f899438a54d490e9c255c222f64ebc4165a95822964242cce9773968271d15081e821931ce05f265441a226d8435ac0a163849c945ad9a3e29c64fc4ff8d298f46d683ca240f0fed020189a9835c592d67777e3b0f559be8dbfd377594a28a55a85fa8d415e190616eb0e2a4039f8cb9c6a5c8251709b4fa9992f576fdba9355dd283d6646b90a80b2e7c54d4f69c97366f884571c5548cc7c5671d76ca5664abbf75bcec6ce22554a68c023b98d1387090f91f0318d5092c667e2124da5540aaa5c4e2dd6638d7751940dea57df2726e151e5a2332bd5d608e169ded8e4f2adb9cabe03afa2be4641879a36e40054dc2f5be00405b71ddba7774991678b6e39cd2c7215ce06e1bedc8b004af437b579273303f8637840487002ff38d176274c156617ddf1173653a9967df61a144b61942b6093d18e0a631ab58539824a70b7b181d36339169d3d44f903fea37818983d663baae9401d3edd00e3ed6d704784d2208d584c5d486e723e11691b4ec8cb164c78c4208e24f0d81a33d178a4eae516a0130c499cb56a4ca4d5b1e54c73e28c70394db17539a958a036123157e97612caad06011c57c5e0be2484d17ee7304824845aa2c0142280e5aae956264e71865958c671652c4f440583cc4e9df15235d90b2c8d5298bb9551de2c14cbfa90cbd283d6a4057661582b55da53e2d37134
OutRec = 0300002000040000c0001000000002c00000000c0002400000000400000000100000000300000000040002000000000c0001c000000004000080001000080002400000000400004000300004000200000000040001c00020000000018000100000000280000000040003c00010000c0001c00000000400038000200004000300002000040000c00000000c000140002000040002000020000c000200002000000002c000300008000040000000080002c00000000c000080001000040000800000000c000140000000080003000000000c00004000000004000140001000040000800000000c0001c00030000c0000c0000000000003000010000400000000300000000080002000080000800000000c0003800010000c0002c0002000000003c0000000080003c00030000400038000000004000300001000080001400000000000024000300008000240002000080002c00030000c00030000000004000000001000040002c0002000000002400010000000030000100008000300002000080000400030000c0003400000000c000100002000000001800020000c000000001000000001c0003000000003c00010000c00028000200000000340000000040000400020000c00018000100004000100000000000001c000200008000240002000040003400010000c0000800010000400018000300004000100002000080000800030000c0000c0003000080000c000200008000300003000000002400020000800014000100008000200000000080003c00010000c000000003000040000c00000000c000200001000080000800030000400010000200004000300000000000000c0000000080000400010000c00030000000004000040001000000003c0003000080003800000000c0003400020000c0001400000000c0000000000000c00030000200004000240000000080003c000300000000300002000040003000010000c0001400010000400020000300000000280000000040000000000000000008000100008000100002000040002c00000000c0003800020000400030000300004000280000000080003000010000c000380003000080000000030000c0002c000300000000080002000000001400020000800034000300008000340001000000000800010000c0001800030000c0002c0001000040003400010000c00018000000008000140002000000000800000000c00010000300008000040002000000002400010000000038000000008000280003000080000000030000c000080001000000002800020000c000380003000040001c0003000080001400020000c00028000100004000380002000040001c0002000080003400020000c000240000000040001400030000000008000100004000100000000080000000010000400020000100004000280000000080001c0000000080002c000200008000140002000040003400000000c00028000300000000000001000000002c00030000c000240001000040003000020000800018000300008000000001000080001400000000c0001400010000c000180003000040000800030000c0000000010000800024000000004000280002000080000800020000c000280001000080000c0002000080000c000000004000280003000000000c00020000400018000300008000380000000040001800030000800004000000008000000002000040002c000100004000240003000080002400030000c0000c0001000040001c0003000080000000000000c000380002000000002c00000000c0001c0000000040003800010000c0002c0000000040002400030000c0002000020000800008000300004000340000000040002c0001000000001000000000c0003000000000c00030000200008000140002000080003400030000c0000000000000400014000000008000380001000080002000030000400014000000004000080002000000002c0002000080003c0000000000000000010000c0003800010000c000040002000040000800010000c00014000200008000080001000040001c00000000c000000002000040002000030000c0003800030000c000380001000000000c000000000000000002000040001000000000400004000300008000140001000040000800020000c0002000010000000010000300008000280003000040003c0002000000000000010000c0003000020000c0000c0001000040000800000000400018000100000000380001000000000c0002000000000c00000000c000140001000080002400000000c0001c000200008000000001000000000c0001000000003c000000008000040001000080000800010000c0001000020000000038000200004000040002000040003c0000000000002800010000c000000002000080003c0003000000000800000000c00010000100008000080003000000002400020000c0002800010000c0000000030000400
Key = 8b02bb704b579798db6aa226b731347518155ce79f24d9005c79f17d5baa5b1d
InNoiseS = 55d10f4b48067ba8ef2308defa0285cec13987c82d528761f851ce55ef4f40659ebd2f0b6deae54a28ad4dcdcff387b99a8e4639c0cf354127186a92f6c0b1735f6d34d89596800646533332b2e5dab016a3d5129f8702223a94003c03774bb2061d322a86d3b7727904414df6c1c03c1a680863a43a09a862e6a0a0921eeb4431188c4c7b79edd293f24c3a1496763936b23d599d922b82663fe59836743d843046d5ac7493a95e36d16b770b7a47bf5b958355fc289c653e4637dda5ea68d40253440eb96f5976ad7a6248a138e760352792267249e91239050d4cf24406a57b2d98025bf104e587632aa7c52f65e781561b0e71c5ce16f371fe50da1f6008f2824828523fd3e2a201050b17a2b474491d49a0b36c8c34eea3adf9339c20a651d6eaa5205f406d933113816e1b5e587ad49a09de8e6e6630f60ed96163833a8560385c1b2124f165ece2ec52af9a9b612f9dc03a81190e5f46eaeda60faa0b7fb79c047207cc4e48078a46a0c49cd1132e9c9a00f85a193551a8cb4b99ec1d6c07491c114969b652935a82bba252326dab5440cca66fe24c37fae468a32b22d21540862f062c148fbda0f0a320ca12ca1ddadc661b19b45c461a38171ad57da96b89c01aba52ce596ebb325a22016e2070d5420284e4a319bf521480181ac4294d28ee037016f03149ad538e632f3c274a162e93b982079fa85aeadabe3cc58671e4bc0a2604243037ae98211789dce0b5a59dd89cfd5b13c56c97d520d73a4c373501f604c3316ce255df320b9494d10d9415faed012ac6b53400bc6d47e3307852697a142c4a9bd28a16b11cf93af3914d31e020ebf4ce8dd41aae69e8885ba641b47352212e69c03f932c5c4d54687a3503288ef5c3d6ab83fcaf2059e9098b59a898c7801683d636e45cbbabd1d8268606c3764111666fc3d57845891126dcd9faa5191a8bdae12466d62cffca274b10129b5d1d5caba36c15bf1e7de911b471a3c7a82ac6ea2374122e2770f8237c0d48e4e25c112b2f6659582567088482c9e9e0789191d226353878202120448980a6b7069bc71bde617452fd2317ed4e989f771032c46ba99724806f5998c8e8fe940b7ea24e6291ea5e550e7e5e2088dcdc6c60dee55496f22c870ca597357d728a9e45c4a8a44c984f48a62281a994098558f77eb70d2b690601a92c8327ea246355744ad97d912ca63d84eab3e0cfa521ce800699989a79269d10fb9285826da751db0dee4c716eeb946b59bf312226e7b95171915ea15615a1bb1c59a749cfb12761edd989e08a79079af4a781dc4f5d6056a91a0661742e5d54673a6c1cec1013739c2e71df299942769ef25da2e5daba26f9addc5155a8608aecbf53254c2d27a588b0823aa54d0bc24a2131b7d842edb3f9666a798f3e86abfe279d86259165bd93e8e7f913ab7d14a94f40cb44062a3d2728e9029ebaa6865be89d7d052c049e7389ca866022c267a3392f689d7ae627fa3b58141ab762d10be4e6d8752edd88cfa3985bfc723023dc380398ee9d9b9b9153a5a06eb295858397fd7719400f80e38aa18fd1eba6c324b15726f4907b84897aa3ff347578a13f1b905a148db1ffe55813c17831f54ab7eb52b44545427a25c17481d0851b590c4e1ea2682139c421108dd2bda3fdbe90549a7548e1463cf0a51e4abe1c171f4866191cba036d270248635c48848fdcb690a0bae3240029cbd688a4d6f150d08d6a0b4e62e2714e57806aad69420c71a72788c996b19b5fd5870506262b878e354056ed2dc4cc6bf00e59acd15ef776d1ee75970799c95a5a32814f8e790d459d32d4ccd807117acf2d2ff290a57342e9b439fbc6163c268953fcc0444d5afd040dc035a3aaa54884c09b4d60f2c0cf2c1e91cb1dd5573e26f3ca8609d3d582c926d429005891c02699e5d3c40eb203a8641fb8bc5dc13a04e832b954cc0003988ab691495e5662e21afb22ba667836bb7f177301005ba3124e4f947f851e5de9b8042b5da3476cbee91e588626da672217be58d146a2f3eb590be8832595455972b5531a87b1e63c20ec19bb9ee925ed1d5c7765b19c199769920d8c4ee6d7eaa3973995011e9e77c6de17662beb49ee169dcda4c6d7091459794277a0418c55926bbbc83a320cc38de4126612a3bd8a55ebfaa897c9e17082319d71b2c964ca7471721e96c69bf84d2ce9149069e119b3f40617d20dc20404dd587aef66972f14369056e2673c5cc54877f69bf8e0ada3527c58c9d8c408ce218c04858e5b94c4ba2e2da592b4c0bfb2c9e0a894e614e7a21baad239149743d1e4b3b068c5c324e1080c09eeca22487b2d807620ff20f64eb1ce404ff82f3926c0673b4341c6a6a1005b08e1fd27578ed1373af6879be3159b2cad27a29eb0c9fab2358258d0a946b1396e6d007995c291cbee1837b4454a13c84aa7b4da799bdebe33b9d2879d11f02008c82a7f9d48c33e5c57a74f731496b62a180db690406a9d8828c13550093aa1a29309ffb96adb68cda1a1089a
InPK = 73ae7fcb7366049e5c2060340422d555213529f573740c28c3f7e11191d2ff660c2c9789d31cc5cfc91227e48ec3c9593df0524f9998904f8d04d3a82de231ac4760a3097911c216159909a08c42195a7661ee825a93108560d582792bb5566f900ff301118ae6607d8282bfc340de1ea6463cab4734ad43e15dea831c599fea681947790c8b1ae4f24ed2460b68d371b24c80474ce5a551418bfed86f0349695f6adf26da3e9a65d3913e29f96eb9ad94452847d43b0aae7401d46aa384108de8ef5a906299744b19ed4f62ae99a6bd18580b6d736ac04a5c450901b8c61843470c23d37b964a200863097bce54f9588db1ca487107eed30630b013774770f881e9375e99ab44a978663d1a22b0bc3e38e19e4f1042e07fb8c3340873b60def9f9cd605eeaae4609742139517ce5f4080ca3a2e6b189b4bd26a6700d6bb7bac648774962aa27ec4a9c5c89c9b264d0757497b88825859cfa682db002a9665864b5a1d9154456a1872321e6f596b87a810aa3cc326070a06be443d5894e981bc4552abf2faadbc37a356f8e5f0655847a6d7aa8e8dad54442ce0154546f784609855b677986523c111b54221dc88e7a2519500da5cc2e9b0ab31db066aff6e3c1de5de84f8893ac361f494130943c724dd563070a23c0f7601ee0077f46b38033f2d493d29c27062953d7594f5c2381e5500ed684550b40959ce1a8327b474288e0fb052a0466a11239574f9ad38467541aa1276cee8aee57b3ea1f20d8cb40f74925415e8099c896e6fcefbd8574a47496028db135433d888690a701118bec07ed04150956586ef56a4321aa18a5197553aa37d1ab9a8d4905f4ece940b7442447f21048b562e75e490e46313a21866ae6be3951e3b9d8c56c940a46746d18b285e1c5409e5c6007b8214d8976e101c161e1e9aef577614b08b1db9d4ebcc2c568598e5d35a45394233254a651dd543db9081ee320207e173732e3c3f19707a0db288e2635029be6e7266d37332994c52e3d445573aa088abcb5faaa5de1dc801112649ed8f4e95190091e00482024a96d96e1a0b14d7c3374c2df96689e53409239f03d9e576c9a3da4725d4dbc58aab1f36a4ce346102923a9052f95703ece5208e9cb6580c9006fab2520549ec5ad3ea5ffdd7eca486a016cea353e89918a8aaee98fab66493c5e8ebb6e7b90da7ef7a812ea497541065098b265200ec25c6d4ba175b6b26e3b03c550668bed246ba5d178f260693858897969608116250652146d3819a5535efc598ab217ea94587042c15711590b3c0e746286a8c521806d99329a8f424c9046336578e85ab3e17ab40657a86b6b4dae8de63bb0573280417c7dfda172320613122592ed64572d38d94864884642553190af01aaf4a5439499883ded55a7a2e3e6b7fa06e909b225e48513cc82fcbdb9c497cba02c06eacc707d5b4825ffad9ca16589fe2c7a365de96b7e2d1a3b7a54ccad5f0f0777834a41ef870ae4560158d35e7e12902b26325d5e52d3efdca6290e3b601f581454236c89d1d9ba978760eaa1018fef4482a6111eb871024d81429915ce552852bfb561ed55bf14eae24ddbaa024935aad9523dc8e7b5dc72b933404ae6dcfd97a8cfe27865774966d74b8cf53df557f8d9b8203fc3824dd44658c23e3e39da6d0c9d007960469768352c42a6d8e34940d93582559494ef581b7b2a45c294de684718ea09009aa1778925818d86b0ee8a76bee470246e480b76716497aac21a9173d1657488a24ac57824174372e89e8f369586ee4545a06c2f960ccab7e21237d9b0a44243082201c57d7e69be972b5f899438a54d490e9c255c222f64ebc4165a95822964242cce9773968271d15081e821931ce05f265441a226d8435ac0a163849c945ad9a3e29c64fc4ff8d298f46d683ca240f0fed020189a9835c592d67777e3b0f559be8dbfd377594a28a55a85fa8d415e190616eb0e2a4039f8cb9c6a5c8251709b4fa9992f576fdba9355dd283d6646b90a80b2e7c54d4f69c97366f884571c5548cc7c5671d76ca5664abbf75bcec6ce22554a68c023b98d1387090f91f0318d5092c667e2124da5540aaa5c4e2dd6638d7751940dea57df2726e151e5a2332bd5d608e169ded8e4f2adb9cabe03afa2be4641879a36e40054dc2f5be00405b71ddba7774991678b6e39cd2c7215ce06e1bedc8b004af437b579273303f8637840487002ff38d176274c156617ddf1173653a9967df61a144b61942b6093d18e0a631ab58539824a70b7b181d36339169d3d44f903fea37818983d663baae9401d3edd00e3ed6d704784d2208d584c5d486e723e11691b4ec8cb164c78c4208e24f0d81a33d178a4eae516a0130c499cb56a4ca4d5b1e54c73e28c70394db17539a958a036123157e97612caad06011c57c5e0be2484d17ee7304824845aa2c0142280e5aae956264e71865958c671652c4f440583cc4e9df15235d90b2c8d5298bb9551de2c14cbfa90cbd283d6a4057661582b55da53e2d37134
InRec = 0300002000040000c0001000000002c00000000c0002400000000400000000100000000300000000040002000000000c0001c000000004000080001000080002400000000400004000300004000200000000040001c00020000000018000100000000280000000040003c00010000c0001c00000000400038000200004000300002000040000c00000000c000140002000040002000020000c000200002000000002c000300008000040000000080002c00000000c000080001000040000800000000c000140000000080003000000000c00004000000004000140001000040000800000000c0001c00030000c0000c0000000000003000010000400000000300000000080002000080000800000000c0003800010000c0002c0002000000003c0000000080003c00030000400038000000004000300001000080001400000000000024000300008000240002000080002c00030000c00030000000004000000001000040002c0002000000002400010000000030000100008000300002000080000400030000c0003400000000c000100002000000001800020000c000000001000000001c0003000000003c00010000c00028000200000000340000000040000400020000c00018000100004000100000000000001c000200008000240002000040003400010000c0000800010000400018000300004000100002000080000800030000c0000c0003000080000c000200008000300003000000002400020000800014000100008000200000000080003c00010000c000000003000040000c00000000c000200001000080000800030000400010000200004000300000000000000c0000000080000400010000c00030000000004000040001000000003c0003000080003800000000c0003400020000c0001400000000c0000000000000c00030000200004000240000000080003c000300000000300002000040003000010000c0001400010000400020000300000000280000000040000000000000000008000100008000100002000040002c00000000c0003800020000400030000300004000280000000080003000010000c000380003000080000000030000c0002c000300000000080002000000001400020000800034000300008000340001000000000800010000c0001800030000c0002c0001000040003400010000c00018000000008000140002000000000800000000c00010000300008000040002000000002400010000000038000000008000280003000080000000030000c000080001000000002800020000c000380003000040001c0003000080001400020000c00028000100004000380002000040001c0002000080003400020000c000240000000040001400030000000008000100004000100000000080000000010000400020000100004000280000000080001c0000000080002c000200008000140002000040003400000000c00028000300000000000001000000002c00030000c000240001000040003000020000800018000300008000000001000080001400000000c0001400010000c000180003000040000800030000c0000000010000800024000000004000280002000080000800020000c000280001000080000c0002000080000c000000004000280003000000000c00020000400018000300008000380000000040001800030000800004000000008000000002000040002c000100004000240003000080002400030000c0000c0001000040001c0003000080000000000000c000380002000000002c00000000c0001c0000000040003800010000c0002c0000000040002400030000c0002000020000800008000300004000340000000040002c0001000000001000000000c0003000000000c00030000200008000140002000080003400030000c0000000000000400014000000008000380001000080002000030000400014000000004000080002000000002c0002000080003c0000000000000000010000c0003800010000c000040002000040000800010000c00014000200008000080001000040001c00000000c000000002000040002000030000c0003800030000c000380001000000000c000000000000000002000040001000000000400004000300008000140001000040000800020000c0002000010000000010000300008000280003000040003c0002000000000000010000c0003000020000c0000c0001000040000800000000400018000100000000380001000000000c0002000000000c00000000c000140001000080002400000000c0001c000200008000000001000000000c0001000000003c000000008000040001000080000800010000c0001000020000000038000200004000040002000040003c0000000000002800010000c000000002000080003c0003000000000800000000c00010000100008000080003000000002400020000c0002800010000c0000000030000400
Key = 8b02bb704b579798db6aa226b731347518155ce79f24d9005c79f17d5baa5b1d
InRandA = 711d61a7cc0a64ee994d801efabd24af23056beeacddc2a453dbb25eaf9b22d6f8aa0cf11781712ea06ffeeb5adb4a20669ceb8e8a6f7867c55dc376d941a1300e68b06110738e1fdad3c68ab12bafb8d1ed723eb898ee9631304bd843dcd69c6a3d7659a872f74529ad5ab697b285361702dad750299cdd0d3f10cc680b94134898200463ee1d45e688520118cc162872fe87aa6707c57e291d490e6ea92f624f1218212ba4d08818960676831c2d21939bd680be8c0face78192423b97a37f4aad65ab00d24fa7aa8a13ef6987716ce45a2bddea183c5c37a6a64faa3c1a345f0ab811b768454c1b9335c5cd8db96e657a0cd635a20dec30ef425e18957053f28174f9514613a7685fe662c007f61a309959b8a09b22b341630c86f04870af4c57c64e6181f0047d955a2516b546fda3799e8ec3472982a57d249f29e88bb26064541da9a8867975acaf7861ecac944b2e37b8f7194a725342505e9855334d5dc6c7d8ad864856bbcf50490f23fe86e452b04e0134f6665295c26da31211890b9c5ce243713904415f8e71f42c0955e723815f7cad3726fc2a3ca861e7095f7277ceacd9a88f93c71eb70a9bfc600d7d959ad6171be74c29ca4d980676120c59879bb1de4c4369223e15c6f43d8b1e4e94344636f8496cea5f8d696f1414e3c5a20d239c75d0d21289615c2ad12c9654c623b24ae0008a342d8994c0ecaeb211c5079fc81d7ec6b0407d6ab042961d0962b21e23e09f11a39459095e58b8fc30b93618797954e1b87a0c7f42b5e28591c7cdd2a58e6f039a4ad3b054a328dfc0daf276b586dcb4c426c4406aa528f5f4fc497483312b7d3825b30cdfc6756852404c148bd751be30d2143a2ff2383d4fc3419c417c2093766355e938fd43263bfaedbeec42bab1d9f6ad8e90aa58d03c033720aa30d679085b4029a2cc048ae8545b791a253efea4464ad8d6b44b561395679c418e6a6c67cc7147218ebcb4dadd1d5f8d0dabbd79538d81b4d22151550dc8bf729cf63338ea5c4a950e2b50e2cec5a25187ad10a12729ad62806a92035eb49cf04e8fe35f1c40811a9987e0d06145a1eaab26d14a7e0e15bb7d4533e42dd2d430de6faccf2a25e3c132579e1a5103ae457a420b25392687a0d813e1caba3b1e11635198cd672eae29a1cd9d97478e2c6189b50b49ed4e68809d0d15035cfaf6943a378d107044f6674f9d811acad9757be85df6e52c082ada6d2688f2a6e12e4760f24abb3ba8f1d9d9456c94c20b3711dd01349fe70b16711f7209f1921e5d81ba25b3ea9af2bb51ed71215dd41a096bccc14ac4476e8e7702f9fd5d19e40bfb2e5164435534f1d48263afa708469b340d0aae57b1020988fae64c662e017ec68a4f7aa5d1b1ec82edf365b62d130e8ff28f6d511f97b166d1bc607b127f4a612e9bc5445f6055e9192529e528be112757a0abf2bf72544199806944e04b53d8e45a08fd96c9939b9874e9803e56bb16608a47cae265fa023d799646e0775c5c0518825000b872b7d65653424b050905e02ee6a732717f5a12b1117923376d9b8a728c3a24828123903426c0c27f9bbba84c94e18259bf2e0010244df8edf6a938ed1787796c32f4d26878e1cd7b520197c8838144f82c5c3a2e5837a89dcd95f6d29dab9d72ea63d41c9e072b67c61a1f182c2368c4a22fd46699e4a5d6a804eb6e974c8642f5ce9aea803522e66f81b21bc0323ae9410673a43683cdf61befa5b19496758ac456155103a38924f613215271c18892ad96dceb7a32b10a8e1e86d9588c7a5ed9690154f4629909e1d45b545f74a14480de196fe58b332a13acb353cad15bb85d87fb458d6b4f225524d3ad87d0985a049572a0f16ca1f81b5f550a4127cf9c9e9b5e39552042e624ebdc96f35f48647a5c5231889db3ba0ab8835aafd76719892990b2b75931568b9213b96d6da5c01455d5407534ca64f7d0a55a47c44f85e221489e42932d80e5d261d39159176dda667b2d2f8173798ae841e7d92b6c3f450ba9172ed635dace2592ccbc477cd72c2661513701262d84d9bc6611da3c26085d6978000f322d80374f6cef19100625972fd08610cc1810d147b6b7700872a4898718a2919d82d3e9f9d8064069d41301f060321e9b19f7851cb36b0f298e9d5cb4104feb8aca16f096390ada458cf0026fe6c74299e35f97b682d82311eda63b640991e651a940c5be02e74b2f74fe4953d61d09278be62956dff441b45434035ab0c9eb05543d8c6a2a480c0fa419b9e999844f5a5f73d4627104de298e80787542730d57d7ed35236be32271f1d034562b8484bfa101926cbb5098fa18f09a1ad54b0d1556598d9178f602b4deda672ea147e8c4e8a5029003f11a1df1cb6e6f17a24010630c908096a3712ba2b94717448374389aeb08c783adfd9491aaea0746481a6a24757712ed94992aa6e6b715974356d061c1449b1bd11cc64eed6b5c24f86b26a872a49936db6b9487c0cef621fe16a248921386c9dc49bb08c1c15d2061
InNoiseS = 4ca10ae48258b14d83e48384f858eae4c130e49055a044c78590f0a74f1a19e8edd427300659bb38647c032c5722a6ac4b05413b4a0dc870ac1b16f25099428b9beb83af39887340a1c4bd986241429eb8eec081442a418b10ac60be94b3e34374a63c5582274aba579a03202666b16f3066985a26b96dd8993e242ccd6a3d9a2d287fdc82da9091830d0886b80bf3419ae968c615521160e85676c96af65dd92ea10e2c520bca4b882326b7b2c131d22d922827c5b41f2f33b281b50e8b64d92ac48a9bc4516a39272018ef5b707223b59bc2e07dd6831015b610b04638aa9d949cb7444c7d3162cf3a088b628f73c93d66375540330ac2d871d4b0405421caa142a0a2effcaacfe5173862deb228da286993d7605db54efd98f122b1949be7a15481fbd23d97d588b7bce9bf4da31481296149138c1b5753caaa9428b6d5f3be48c69979d351525c61532bf5535aa7d72850c294021d1614fda36c781f2ddbf10a4f723e578a596092ec312827ae456cac024c5a44bb68e5175025ce6876aeb1951d022426faab5a0db9d0cf369324a153533fb50b5a5866c77c00524265020b769517d7970918f5d2bc5a6e874332186d5f9e7a3a03aa28a39de5078002c0845c9eb74791088a81b185958e014f95d1219d702d2ec39a772fa82a3c91fc873a991d54c3c0babb64a7bdd15e78232d3b71a1c08bd60e68fc2f5e46348c8b948c1f93860eab88d24b736c785f2a4564a6754492c9c988c786166708d2b240d3da4c3280bd5616c0aff7a81a9a560809766df9b27e014c6c8aa45b38a6416046ba4b560804a90b54c3f5b6a2abaa7149968c8567c0ed07f2ee99218ed52b88bd98624c1c91b9ae1b082b6d07c8697eccc6a953cec576a25cdf548866a1cb03ded4fb26a1afa6c9287050459de64af1aac1572b1509643c6407f5d4a944904856c42f770717adbc701ff3c9f44aae6bea40c50bdd9f1f9368b667286732023d89581e7f872639f19766b65305b07babe9003e631b6a32511e690a864a18d45263c9436a0f1245db4405b31e1d9a6598922ae6f09a61975b3ac27225baa60e1bf6f01b8a0c07988dc9167648e9b1891c3e01a5031260cd52d08cce39498835b9122ef5d4f24f34c7623448294c4da985b5904583bd6f7e301bb911abaf1c778ee1567e8f4df0e05479cf1b5854e0cc7083a4463a96f2aa4d28944147464d249057b13c3eb8e0e93466a70194309f3339ef597459e9ffb5b15a1cf080c34713b819f6051d2baa142b9602460ac3451161913bd960202f68092c456b6ab71c638877f008862904b3fa62b815414e745b2309629d4691e894282c37e70ab15a82a7b055157b481552c6ee3ef7510a9d9420216b7f2275ef64dab95cc86b3e8ffbcaf508bafa0251c4755d287041290b4f6675f22d3ff9c31808c29d8281f2aaa7c7dede72a42592c10b20a35cee60b31b9d67f5ea6adaa33fb3dd911816aa142975551ebd40569bb1fd904a504b7ac811234029921b6b06b28a1df7c2a2ed59a4ad3541f8852e815b08c09444809decfd2904a62d991cc3c6659d6d4c6906d482bc03cce05cbb9ae142264aeda128148084c5b93b831458b061dd99e94e60a1ef51199f550156047901792628c6d5ff316c20be6d5ea59030d6abb624f8909e12a02dcf69f039ad45ffda6113f2f6aa9be6bb934122ae2de84b7a0add8488c052aaf50d0e098d58c7be3c80fe946c566c00b4739fd59aa2de006885b0cb9c65231f5fa760af69a929443aa3252aa16497dcb2c1180f42cca1310b99278a956a07cf540561dc0bb9e8b6b2ea25e57ae52d636b6297a2afbcb6d014942a33ce4869829de6f1ba761b60b6b93f993938884076c1e4976848f8bb6c4486daddaae7fb8073749a70f0eec61ff2c9687184c09bd15f849108700efe8a01b72c9c97d40957b4e3d64533411887541a5de6518ab756994bb5ed9f7af8da0bbe6959c57e4a2f346884a6716a847015c5545d69770d56d44500097f83ee4b736df867029d979848b64a2c281b2ac3d140ed854f12fd946b770754139e0e320223dac9823a14c28cbae29dc4af992ced62ab7255f265c533cb54b75f48a8321e7aa8f7939c468d26645c57b4abf0569260229a40611920af1add758474b8d026f41785559ad04faa501a649e44abee8607fc4eb21376552ba48931156485c7916d4d63247a757d4f92cf34322202b94acdc3276d99a2a899d3471475bb268ef9ea9976a949437e30e168301d027518aeec04ffc4294a00a2649b271b334f3cbdf88678b8b8c583f62c0815937667aede6ae53aec271e5d885a84b58d348449aa06649d6a635bd7d392885a0ae60218d8a085a509f5e5ad12e24c4d36b04600c0011623d4a4bd2206fce8d5003234405db3ad7e3d4dd6aa790abc6b1e49e8b26436ae6c9f1010b1e052158639c1582d641d8b3ed0a9c289aa5eae66e66a43048876b14cf4a69489224564c4932adaaf83e2b15e0b2248425d71198849f534d801b24cccb2aa434829
InNoiseE = 349b8309537882c618c642ab2d78d380e2401039ac30ec4fd00536ad1d6297b1a4cc7dad96c8385cf90ce6e5f6995dfd317a510bcabc18a58ea4959286c491ae000ca949f92137c851e143c574b66e510b66b05ec661bcf0d32a401450af69e8a8943cd8b807ecc8be785a0ce5b840200fdc4c41c7a48fe2625853a59d807452ae647f3d139a97cb66aaf2b4988095d52ecc17e6a9ec41ee8821fbeec2d03d7a2466a0af2a211e718bded74735ac8e6a63cf3b18f16ae61619263bfc065e9c2197b9ca9b48e2ae35ab3c0500684e86c6e55e34a4d37415864578484180f53c500a16b601232987cdd02994ef560a8cc37f205ee27712e4a39104c23ec69e03c98c5c403cd7fc2b3f22aaab0c8dc50e6557995468564c100e37d009228b7a71fc98abe828810d4ec0a208103c1e5068029a86a8abc4e0516a96807de96a38ba7c16bd1e2dcf85d7ec192e9fd9a4822207640d6681b45c4f0d1b1ba2739ea684676278a5259e8166357aa6b90a1cccb8001e7e3aac2eb6c713a9705daf156015ccab64c49509760d4b464462ba92ce812aa10bd195c27e70a6254208929bcf85f5f23f583e1ec4b60123aa3d9217f37a33b19bd120aff2e13ab15a534d669701a9cb650a58958c5900a02938a7fd321cc4d07a0f4dbae65d00d44724377aa3ddd4a37d368995cc85fe5672d68f3c453b286fa5cc0b3322ca8d3eae302b982e732fa369c89ada8d45213ba560797a81d54f437a1e8708856781dbe5a5e013676bdfbebb758d41a500f466aad9ce997fd566a143dd299a5a51494de7aad82a820cc966901b9e0f326bfc01e77e7b78285c60fa0064c0e0cdd5e54112e51667323c9c4f842628c20128489ce13cdbc4366c7ee94791d936adad0c9a290e78931a2adab935664ab195e998108c50490bab1ad28a77f5a6b296dcf51e1b5850d2b9ea41ca1f45d96a1660ba055d1b441cb0702a8460dc1eab7642ee35f352bffd638be7148dae22cb8300e435364fe6481052506a9529426803b236ba6d8497214529a6ca9935ed79bdab27ddf330c20ba1d5b1959e487a206bd6706fd51ae3ecac0a7029485d13c9a84d1a1e0d9446a46d7c046ddef9bb50a5ada49a6f50612906b2423a4a7d30b837e39640b196a6a98175f05ea02c624c57186489be678f7981d5918c8a59ef3618245f45d5182b33ea6f7fa2f92004b043ffc9a4b88bd2b319c5f3a6a1f93511ef5ac6e9c2773beee23533b175cc67b6879840bb002bd6b45055a5f2acb6e8e3ad5cba250510c6758ff59e8257b051a06d8dab789d856165eae7c057c22e6ca3fee36a20052ac6f5f583ce2c1e48b172ca815bf84d263bbeae1d88679df8681661fb0650a48cea4ad15c78355429048a91a847d3c45c72e964db630073049a6ab35a9e1cc15aa979e05e81f8ee5945b289648025f6b86a489bb75023eb0c2a035cd211e5a88a3daa479c53098184359ed6e85a3c3d29e6f6e66e1595b3aa78abccb5485d67a741e211436513dd5ac5047068aa03ab59890bb148d809cd9cbe152996b5e8d266689276105c887b5268ecab7f2e68e045aea8082c0a535f3773ff614527616fc145e8228d2d467144a06077dfeda7ef2284b46dbb7861ba904f19429a15422dd79f4ab4ff912cc8ac83635e611ca79581f487b56c44a2f5f0f84d80f00918802571072e591cf8c81e1b831431117f30ac7e9ae6067f410e03d580231c86141e0ee1a6767a1085c3a1391ede006fdd47d5ea252bd1a723a92abab5a21ea0392f812235c40d7b2930405e2a8278b3e885ed41cb29834d09c7013d06596834bd465856f3e407600c29544380acfaeef9127af55fc150a08b8381a3450913dbc33d5f1591cc27cfa41ed705e8aa8bf872c0a31268fb329a3d14121898d213bca41d43d99c4c37eb0f454e4e8e889f35d12d1818c750ce16adb47eb6e1c006402992490158ba67b87b6cd6d5d787fc953fd66796fb8d1cd6e67d13403c7275d2ec56ce16a0792429f2b374b608ec3cd17a740055c0ef2162cd151d0025b23d6db53249f15409563e49595b26dc3970a8ef890280c64b56de24941208366558d1f601e921335c880af02d52e5ade6757a6019c6648a2a77ba634f802edb4cd0b6cf0f8b4bfbea2cf68b80f4b6f47e070eb87479b1996d1681298ec5445be5ff4761baa0f9a586e4ac2170d75311322c1a30301ee5275bca731052d4688f71774e5a1509f60d163c56fa403aa810f1804cc682cc3b112522917c51613d4fad32f401a02ba0b059c4b1136d07164bf935a3bc14ca8640d597dce54316616a38a41ef7fa54e0178c2111084742bef21667b6d031a5c5a962a23d3229715be995f18438f75168d7a69dac1c8f10b480841c001dbc6997003d0ae87d4424aa3a918b81c17894b16f4697559b2a0ef3ac68e61ea9a788407324235951e2ef01b0a260993c03aad0f00a433c2b40a90518a11eaea4756af408da6181c288fa82bb4c3b625b98096a62d6c15449234a609958e1955dcd40c4d9cb8d14
OutPK = 5455f1b09dc660942d60b9e13ab27b43086b595a47099a78b526a4bff2e3ed7addf47fc796c09adf480b8a091d09111d0999d632d910c03dc1ea867aa458a99b2c9a4795393bb6a417085fcc776a6c49f32a8185e24c7662ef62bbbb184db4e73670a16279b1c0245d8aeb3c6aa93c6eb588f84bc89847e312c8b419fd8305ea392a32a297c449ccf51ba56ee566a6e91c9cb46417a927bd688bd0223232db5c5f62d85bf3bbbe2ff0021dbace3c8f3a6fd3991e70a277c2390a64b64c43907154d83e779e0358426e090fba1a3676c94652e20a40f3dae5bf08952265706a9fc942991a3cdd56265f48768096287598c820953d90728c57b0fd352be0db8e677824a7f92b6ce9bf68721b2251547f392200c5c2625448b11a8dc7a0bce8b6f0202a24b65d63a6d7479b474543d2d6c42508c8724996c335134553a6df4d88d5ac44560023a009d5561bd0a5d0d65859ffde9070bb2c72b616ea62b1647a0263d1ca4f3e7d35267e00831eb1dbc2f9a7a7793d1d6d575b77e6686b429cb771fa928fd55b0b48d4266f557b49800083f6425f9653f84763dafb03c8dea5aede1f86e69d37148da13afa4d9ffa4a435a23a93aaa1175224ff2667524ec7a8af29c518784e6f43c657fc4a023a2da2773ea7d19cae499cd5f244473aeae2865b92bfc248212e843c73b6879f769f9b5a8757e1fc4f61ba801613e8c004a61516774e159e14ba972b3cd3d77e3f6b4f093aad5906d91f6c4b9f19cb158e05a652135bc11e89735f4b6bc2fbac84ab8c849644d1678522e3109e8ee32d3a1c407e993d311b0baaaba5aeac6ed11a904092044e8028964044b01ef56663b908aa3cb2a5fdb23121aa12d80ced256d5501a57f1c99ca0a69848859b8ee4484dac685a02c2c37a7baa0a0b7029d1190e89dff2e44d2afd5461c2f05a040a0be2e0652e4e9c041e3405112fa12e869069e1081666c509c60186b512b822274d27c9c78f413fcdb48097692115a461daa70688fc093ed22d9663818e238a25a0b2413176e1687f20320c8efa9d2666a2444d88d452717e0608c98c91fab266143bdf5698b8ac22de8576c672da2993cf0bd6c2c638f19ca672603da4355226a71e8465bc51cc96ac7c34a0e91a777962249a6429a6810405828093709d9cbe465c446371188ce0c4caaaf1849210cc5ec084fe2de62773191e3d9c7290caa4952c0a5b2ad4c4b6907c616a55a8c7768d1b9b45b8872819a4e44b47a3c92f86411c14530db4d82a83c0678e22834408d342117fbb414d8979718499231f43a960281ca12974a6b08f2258a7879a3c67d0afaa6451c9167a4c79d04c909fff62d2ab71e116ea58dd41057487db414bea87b925e5ca33c88852a71a104d3600942fac9119a7512054b32d7b57e23554a026d7510996738d844792050519d5a0226812ba5a1998098213008d08d91f14a2b8088b5ccf2a5e003bb84bdaf9e25c4d1692420400c19f21d675f686290df3295ff814de1e3c09d74504696e0ea29d357e76b813d2339880f293419098851b665fab0dee933352274157f944701459b9da26c745fe73729e7757f46c03066e9ab8e1a863a8e1a430ab719c3b0e342617d80859c200b787996abc02b00232728741cb34c4478644846acfda8f393789e259abf7fd67a188c3382c0d8c0c4d427b5e2e8650d440177ea64e3720e6e8a4864c7cacdd65f25c2817c5b2832be22ba31bff60e540318449f9f55451aa04db2215846d9b794b949b09e66f59e84f70f278bce0aaae026e79132c8be008ae6db23869e58b2c9695149bdef339753759043463628c2690d6aa352c1410f0e99ae326fa9b678add542c9e2a44d1a3815aa06c5cd6f5b2c7023db2ad0b6773c4121ced854a27ed579189a014f5fa43d38cddd1b412a8ca6410a32e553d70e5d4d90a84986cd0abcaab4e73f0cdc68b6d7d710d5e9b83ff482f37a8237289255001801aea39a5641da06a21b3ea2dcf057f27c210acd300750a06c991e7633942204897101182fa9f2049286143ba79666f18905719c0e879d7d442e4c7a537c713597308b54f261963f7e8bd82725e5e8837e23253667427753d78db5f22e5891eaf9b459ed8f86516769a44c03a528d45ca13067056225b430bab658496220edbe3a70c5e2daf0736da80076ec85ea08cc259a40f412296861d37af6f38610624291e7f410abaa56edb34c20ecd2bc8c2e4315b3850bae021906498497912a70266259824976aa9eb88049c4b08f6876063dca72331c5a9ba0e2f8e21e0668db8d1c105566e39c51910268e551dbb146a9aacd8a457a91e49022e8eb318d216dcf086454d0a88a5ea27364a27d3b585757ce194255d857d9b12e648661659c4c16a9b954216bda445863828ab799d45b61184b8fad5613199eca1cb59a5c69c4843d8a8dd0ab9c149f6035dc26cd4bdb59fa3b6ee699781cf3b06977d22ae472155bb5e64c96b1241f5e67aaa2b73335032aa34da0ee50a0145e92ad0f2011e57151a3f1a01ee5b
InPK = 5455f1b09dc660942d60b9e13ab27b43086b595a47099a78b526a4bff2e3ed7addf47fc796c09adf480b8a091d09111d0999d632d910c03dc1ea867aa458a99b2c9a4795393bb6a417085fcc776a6c49f32a8185e24c7662ef62bbbb184db4e73670a16279b1c0245d8aeb3c6aa93c6eb588f84bc89847e312c8b419fd8305ea392a32a297c449ccf51ba56ee566a6e91c9cb46417a927bd688bd0223232db5c5f62d85bf3bbbe2ff0021dbace3c8f3a6fd3991e70a277c2390a64b64c43907154d83e779e0358426e090fba1a3676c94652e20a40f3dae5bf08952265706a9fc942991a3cdd56265f48768096287598c820953d90728c57b0fd352be0db8e677824a7f92b6ce9bf68721b2251547f392200c5c2625448b11a8dc7a0bce8b6f0202a24b65d63a6d7479b474543d2d6c42508c8724996c335134553a6df4d88d5ac44560023a009d5561bd0a5d0d65859ffde9070bb2c72b616ea62b1647a0263d1ca4f3e7d35267e00831eb1dbc2f9a7a7793d1d6d575b77e6686b429cb771fa928fd55b0b48d4266f557b49800083f6425f9653f84763dafb03c8dea5aede1f86e69d37148da13afa4d9ffa4a435a23a93aaa1175224ff2667524ec7a8af29c518784e6f43c657fc4a023a2da2773ea7d19cae499cd5f244473aeae2865b92bfc248212e843c73b6879f769f9b5a8757e1fc4f61ba801613e8c004a61516774e159e14ba972b3cd3d77e3f6b4f093aad5906d91f6c4b9f19cb158e05a652135bc11e89735f4b6bc2fbac84ab8c849644d1678522e3109e8ee32d3a1c407e993d311b0baaaba5aeac6ed11a904092044e8028964044b01ef56663b908aa3cb2a5fdb23121aa12d80ced256d5501a57f1c99ca0a69848859b8ee4484dac685a02c2c37a7baa0a0b7029d1190e89dff2e44d2afd5461c2f05a040a0be2e0652e4e9c041e3405112fa12e869069e1081666c509c60186b512b822274d27c9c78f413fcdb48097692115a461daa70688fc093ed22d9663818e238a25a0b2413176e1687f20320c8efa9d2666a2444d88d452717e0608c98c91fab266143bdf5698b8ac22de8576c672da2993cf0bd6c2c638f19ca672603da4355226a71e8465bc51cc96ac7c34a0e91a777962249a6429a6810405828093709d9cbe465c446371188ce0c4caaaf1849210cc5ec084fe2de62773191e3d9c7290caa4952c0a5b2ad4c4b6907c616a55a8c7768d1b9b45b8872819a4e44b47a3c92f86411c14530db4d82a83c0678e22834408d342117fbb414d8979718499231f43a960281ca12974a6b08f2258a7879a3c67d0afaa6451c9167a4c79d04c909fff62d2ab71e116ea58dd41057487db414bea87b925e5ca33c88852a71a104d3600942fac9119a7512054b32d7b57e23554a026d7510996738d844792050519d5a0226812ba5a1998098213008d08d91f14a2b8088b5ccf2a5e003bb84bdaf9e25c4d1692420400c19f21d675f686290df3295ff814de1e3c09d74504696e0ea29d357e76b813d2339880f293419098851b665fab0dee933352274157f944701459b9da26c745fe73729e7757f46c03066e9ab8e1a863a8e1a430ab719c3b0e342617d80859c200b787996abc02b00232728741cb34c4478644846acfda8f393789e259abf7fd67a188c3382c0d8c0c4d427b5e2e8650d440177ea64e3720e6e8a4864c7cacdd65f25c2817c5b2832be22ba31bff60e540318449f9f55451aa04db2215846d9b794b949b09e66f59e84f70f278bce0aaae026e79132c8be008ae6db23869e58b2c9695149bdef339753759043463628c2690d6aa352c1410f0e99ae326fa9b678add542c9e2a44d1a3815aa06c5cd6f5b2c7023db2ad0b6773c4121ced854a27ed579189a014f5fa43d38cddd1b412a8ca6410a32e553d70e5d4d90a84986cd0abcaab4e73f0cdc68b6d7d710d5e9b83ff482f37a8237289255001801aea39a5641da06a21b3ea2dcf057f27c210acd300750a06c991e7633942204897101182fa9f2049286143ba79666f18905719c0e879d7d442e4c7a537c713597308b54f261963f7e8bd82725e5e8837e23253667427753d78db5f22e5891eaf9b459ed8f86516769a44c03a528d45ca13067056225b430bab658496220edbe3a70c5e2daf0736da80076ec85ea08cc259a40f412296861d37af6f38610624291e7f410abaa56edb34c20ecd2bc8c2e4315b3850bae021906498497912a70266259824976aa9eb88049c4b08f6876063dca72331c5a9ba0e2f8e21e0668db8d1c105566e39c51910268e551dbb146a9aacd8a457a91e49022e8eb318d216dcf086454d0a88a5ea27364a27d3b585757ce194255d857d9b12e648661659c4c16a9b954216bda445863828ab799d45b61184b8fad5613199eca1cb59a5c69c4843d8a8dd0ab9c149f6035dc26cd4bdb59fa3b6ee699781cf3b06977d22ae472155bb5e64c96b1241f5e67aaa2b73335032aa34da0ee50a0145e92ad0f2011e57151a3f1a01ee5b
InA = 711d61a7cc0a64ee994d801efabd24af23056beeacddc2a453dbb25eaf9b22d6f8aa0cf11781712ea06ffeeb5adb4a20669ceb8e8a6f7867c55dc376d941a1300e68b06110738e1fdad3c68ab12bafb8d1ed723eb898ee9631304bd843dcd69c6a3d7659a872f74529ad5ab697b285361702dad750299cdd0d3f10cc680b94134898200463ee1d45e688520118cc162872fe87aa6707c57e291d490e6ea92f624f1218212ba4d08818960676831c2d21939bd680be8c0face78192423b97a37f4aad65ab00d24fa7aa8a13ef6987716ce45a2bddea183c5c37a6a64faa3c1a345f0ab811b768454c1b9335c5cd8db96e657a0cd635a20dec30ef425e18957053f28174f9514613a7685fe662c007f61a309959b8a09b22b341630c86f04870af4c57c64e6181f0047d955a2516b546fda3799e8ec3472982a57d249f29e88bb26064541da9a8867975acaf7861ecac944b2e37b8f7194a725342505e9855334d5dc6c7d8ad864856bbcf50490f23fe86e452b04e0134f6665295c26da31211890b9c5ce243713904415f8e71f42c0955e723815f7cad3726fc2a3ca861e7095f7277ceacd9a88f93c71eb70a9bfc600d7d959ad6171be74c29ca4d980676120c59879bb1de4c4369223e15c6f43d8b1e4e94344636f8496cea5f8d696f1414e3c5a20d239c75d0d21289615c2ad12c9654c623b24ae0008a342d8994c0ecaeb211c5079fc81d7ec6b0407d6ab042961d0962b21e23e09f11a39459095e58b8fc30b93618797954e1b87a0c7f42b5e28591c7cdd2a58e6f039a4ad3b054a328dfc0daf276b586dcb4c426c4406aa528f5f4fc497483312b7d3825b30cdfc6756852404c148bd751be30d2143a2ff2383d4fc3419c417c2093766355e938fd43263bfaedbeec42bab1d9f6ad8e90aa58d03c033720aa30d679085b4029a2cc048ae8545b791a253efea4464ad8d6b44b561395679c418e6a6c67cc7147218ebcb4dadd1d5f8d0dabbd79538d81b4d22151550dc8bf729cf63338ea5c4a950e2b50e2cec5a25187ad10a12729ad62806a92035eb49cf04e8fe35f1c40811a9987e0d06145a1eaab26d14a7e0e15bb7d4533e42dd2d430de6faccf2a25e3c132579e1a5103ae457a420b25392687a0d813e1caba3b1e11635198cd672eae29a1cd9d97478e2c6189b50b49ed4e68809d0d15035cfaf6943a378d107044f6674f9d811acad9757be85df6e52c082ada6d2688f2a6e12e4760f24abb3ba8f1d9d9456c94c20b3711dd01349fe70b16711f7209f1921e5d81ba25b3ea9af2bb51ed71215dd41a096bccc14ac4476e8e7702f9fd5d19e40bfb2e5164435534f1d48263afa708469b340d0aae57b1020988fae64c662e017ec68a4f7aa5d1b1ec82edf365b62d130e8ff28f6d511f97b166d1bc607b127f4a612e9bc5445f6055e9192529e528be112757a0abf2bf72544199806944e04b53d8e45a08fd96c9939b9874e9803e56bb16608a47cae265fa023d799646e0775c5c0518825000b872b7d65653424b050905e02ee6a732717f5a12b1117923376d9b8a728c3a24828123903426c0c27f9bbba84c94e18259bf2e0010244df8edf6a938ed1787796c32f4d26878e1cd7b520197c8838144f82c5c3a2e5837a89dcd95f6d29dab9d72ea63d41c9e072b67c61a1f182c2368c4a22fd46699e4a5d6a804eb6e974c8642f5ce9aea803522e66f81b21bc0323ae9410673a43683cdf61befa5b19496758ac456155103a38924f613215271c18892ad96dceb7a32b10a8e1e86d9588c7a5ed9690154f4629909e1d45b545f74a14480de196fe58b332a13acb353cad15bb85d87fb458d6b4f225524d3ad87d0985a049572a0f16ca1f81b5f550a4127cf9c9e9b5e39552042e624ebdc96f35f48647a5c5231889db3ba0ab8835aafd76719892990b2b75931568b9213b96d6da5c01455d5407534ca64f7d0a55a47c44f85e221489e42932d80e5d261d39159176dda667b2d2f8173798ae841e7d92b6c3f450ba9172ed635dace2592ccbc477cd72c2661513701262d84d9bc6611da3c26085d6978000f322d80374f6cef19100625972fd08610cc1810d147b6b7700872a4898718a2919d82d3e9f9d8064069d41301f060321e9b19f7851cb36b0f298e9d5cb4104feb8aca16f096390ada458cf0026fe6c74299e35f97b682d82311eda63b640991e651a940c5be02e74b2f74fe4953d61d09278be62956dff441b45434035ab0c9eb05543d8c6a2a480c0fa419b9e999844f5a5f73d4627104de298e80787542730d57d7ed35236be32271f1d034562b8484bfa101926cbb5098fa18f09a1ad54b0d1556598d9178f602b4deda672ea147e8c4e8a5029003f11a1df1cb6e6f17a24010630c908096a3712ba2b94717448374389aeb08c783adfd9491aaea0746481a6a24757712ed94992aa6e6b715974356d061c1449b1bd11cc64eed6b5c24f86b26a872a49936db6b9487c0cef621fe16a248921386c9dc49bb08c1c15d2061
InNoiseSP = ee8182d96f319477ec31a90e7e466e1fe90abbc0abd2e68e952c659794cfdf901eb0a0c481c3f11a46118f4b9a288f1827fadab55868d020e0818994bab98bfc0db557bdfe3fd4a1295a831258e76af1a85c019da0eb2fc25a5e2c9ba98448e865723e41f7f8a802aeb9a66b40ec249a225848777e05b27e8db160d43d43e847c339342db6fd648020f7a4421fed95b1b84868c6acbc953922173c41b0608cfd7b650d2f13c4b91aaf6600910d2a7d87ed8cb8a54c140c6aad638ff58d79046bca4f38b51801f6f6eafc94420dbc35bf019bebdfeda27d580d439505ba08ea976bc0f68112781399635e14d73622d469af175e7e2eef887575b112744683c3c9f37e78974cb7674104277d9e8fb9af78138c01e96af2105de9001f06e2295aa7a24847384ebad216ff597d787624240df403613d7922a7c68dbe6894cf60b669f8a18a0e84846e05303f68c8a9595c7a1c2e6b82fa14b00a2da0b369660286c1a7a86554a39905b01965665acf1f1a7200297b7382e3eb227dad0de70b30b32c9b495450d83b2072daa1d61b699d1d0166246b6efeb266cbd6729b3540fe14d3b272f1152d29fb405b4c2f2f96adb3e90e51ade8656ac8551054d10f05d51155b796d8dabfa4a35ec06dc325c92ed94a7bf28ed0974d54e8c4d9658f7ea4b7150d14716602e28755ce81a9a197379e25a5fccf49969754ad632f803592055c829ace64fef68ef324100bf61c714d82a9246e09bca1431833a3f0a3ecd4f2609488b172128127c12d6e9818e27a45f5918411c339e92c1dd829555afa4a1bc9d80292b7920400d75128ba54461bc3e5687455501fda0db5e990a6cd8e03a1b8ec54238197c22a017986d5a17722c605c42e493b4260676a9af43a6c5964c71ddd975bd8b49b1de569cc6c89b667ad5334ca7bfd1c0b5ae8c85ecbca5c59e9d84b949b31f2a1594eea92436715dca746435c554b386e2a6265a198b50ffc5c6c460f093ea12fa13718fa445dc0e4161ea6ae71673282905d302aa22d9587d10411d577117e947cca55b344f21141a92acd69296ab9b0583968f959365ca7b9f318c2180489e060e8bda8709bfb10ba75924e803d3466d23e7ee20efa1b964da2823a37fc8660900dc287488d1e918b8df40d0e4c3f059a91c00071ddc81b4836ba143fc22159802a655ddb52c7dc6e6f25aec2e48ea69bc7aacc94e7d00af08d09a0556c0a73d06ef464422c47ac23e0060a07b59ca109c54a8bdc094bc380de51908eb0b4314e1d9b8d3e87e8a621a1e7454445b6a23bd0d391d2fe3677aef161cb40129ca9422a379a379b693ae2b49175a71d758b79ca19ebdc8ee0b926a325e8bef852c96811ab1516fc294459de763b950aa4ba1f11b69789b529db2047ab541364c32dca3dbe29a1244cf56b6e8ebd19373acbe80d8cab9ea7889e3cea625df9d05e5f54e7d098dce2ba89ac7ea8fed87ccfd18d0165d53545405a51525ea325c19f4781f885d5a11ad7868876365e8f403451740a06896b558d593a5c46fb7e29b89c8beef2b0baab2595f611809e97535c90766239a287dc031012a44730a0664a195e225b53e9ab1f4882754dc5293e64328acde9901d7e96d3c32254e28d1c7dcda48564762eee27cf66a1c6813fe6237300e24b719d1d928bf979a4a5b0eb570960396c3c925701496c2e9896d3ccb2ce603c36d052bf3819cf19ac825975ea27a15cd48f2b117a2a37705f081ce6f069c577c4457d2054346acfd66650fa1c4f0547fc9ab1d0742769d44aaf6427cd8c689aa14497bc0b2c3a91fdb07560bd31feaa9a2e09bcdbd529afc7e2ab289a28290c07a273f45c7a10e3559a530876a6cfc1374a7183bf172574cb891e278b2541f2a111abcaa3f09e7cbb24ddc9ca99c555d600aee2592e45c148b2eaf1b5ae562988130f090e301f3f09714834d94cfb57defa53bde222c8cfdc6d7de54e67283a9c9387033147ec77844e9f538fd973639b632280411144ea53930d914e649b6048f22860f3d38f466e38301dedb309e64c5b2cc4e8c35d2e8e932290b9b33d4ced0bf87b8d2a558296c92664c0028c2ddaf499800f9c894283630e9694ad26381e5c92b5c860a279c403e602c929f7323aa4689f5244a8545f53187ab5a239b30167932c2e36c72d12ba671864b9c83d68c04a18ba622fa4654abda3e0f1d11f586e6080d6524bd9783f4a3b78a9992eb6972d95cfb14182448ce89aeda8a399a77abaf8bf56d49a6b294e158d19e8f3716211fa19cb0a2f2655f8ce24e4a101a35c68d5aaaa34bc2fcd4ec3354e2fbcc5a9b8d75d559bdabf02807a59c62fa3e960de7e460baaa4bfcd7a0ca088979bb124fbe5beaa28e42230943526a8fe48e5ad8d5132766415ca2f562a6654c3e1c2f3290c83276db375302267ac09fbf9a3f17ffc010c3367018c7b1b72c6fc6a02bf2d04db3e9a0cac601cca96f44104dfccb7024e44f09c0cd4b2e52666ee4e23f74618ac0b84f24f015f38cdfefbefd6567396ee7593f56f
InNoiseEP = 5a9a43219eac7517ad1b9abd5ca888e84c953f48773e0cec94d4322f4cea9ddb830c1c3de76ea5564a5b3b2ec5476414ac2f4ca4b2b0de57cda2ffa9aaa58feadbeb403f057810881f56b5e60eaca35551eca91f36554610c8cc8cf26b75e939a84803d8ae1584890cd80aa728caad06a12c6f29560c8adda597e43a5d00a2c261fb8a9a37fb816c04331176c48d4670d7085adb9fc3077ed49172a81006448c3bf229724bee26b657eb11957008a653d9156ad76597e4138c866e310d285718a6e3a9bdc6af88b260cc24e9a7dd452fb81f099a464946caa2a4ca2e9b27dc48a2980db3ae7098f55d95d8eb0e19d380f6544119ae0f1430f82dea7490ac46b77cfdae116c4096d0de15c1a3c0fb861011821e80709fcca262a8e4f038c9555f4c17a278881f1e867c9761ea909c9e5aa3769a7e5748b0bb46bd782d212062744243239f1847ad5d9f449b9b80a934b5b702c758ed9a5efe5202caf6192e47aa49686eb612f01944715352b6e7c759802992b3248f7ec4a0d973829131c16a65ac97cca9b731757587a38776ce987d2f5f61f024993e3ae2bd95c7be68a723e590040c14e84ba7518ed54855dab19948f4945fe5771923ea97d0492902b139737a5181b9173a17742e27e626ae6475989bc68aa048339a80a3300879b72a0af0f4ca5f688cc6a6902a790a228356a9f576bcd07de18b583276e4977aa80d60a1acb0e88974a3775f31b76ffc4bcdae32e73f892f7ea1d9c6f21a073dda31a5def64d1e516a4af52c09095d21756dae530c53df12ae9d10916ca672a322893b69389464c0452186bd88897029818d0250df314d2e2efbd803353f431fea4b092854ff6fc5d9444129c49d0313c49e9be0516e414c8420fb2a1c28548d4a0293fce5452d6ff1da977a34a92711ce10480e0581f80fb0609458958f15bf7486447672905552dfce91976a0f261e94bc1eafad76fe7d6547105d0ac5d89d670464367ba27defa406c6f32c0e21166c605ab8ab0f5bf211b78190e9dffb8508f2aeaba52980eec98c3863b8b4fd81b67529132675992c272eb615794156e80a091772442f884d4630aa6e344359fd5694c910faabf198027e1ef5481ecba91245c1ed936a5416ab706796547878703c4126d5267596354fbdc518f95e7396b795de3c7996150a295d82056712e4288f99743c8b740703cd57ca668ad2bd5c50349e438522bd5ba84821a320410b27062fb5f196432955db86a6a88b306d0b71149c9b7d8204ab7cb6bc4299fe5598c490a79d53abd8ce6d71e0948b5dc41f8654f983350c739b1e3cc697a11e5306ca097b75a980d0f37b9044a6c3209570d09ca4cf8a3de989d11bad8abfd9a5254093d4d8482bae4e7125f2a6d27c49ef68aea073a505d86609040cac20029971d33e5c96e76e812114ce83234b56a89f5d8bbbd6a1e4e49a0cd08ee4fb354a6e568bff89d3b234d7e01543de4e60660dbd5b88d9073943e9f3f16aa5da91ad30819d59b94326da3909aaf0e7667394444ffdef93193daa21ed03847771ce981c40438a2ee8b472e494a9307d53254dc7c534dab0bb401a0ba434268022d8a7155e654c14e5709632bc9c2fd507027258edaefe73fd482be81d77b4955d22728819a35d26745edd9672c8a5615c510495abf2bacf93b358c0aa1e13cb6048be4082b95b3cb96015442fcc338677b204f6cacc907f5e8194994dd83b16a592defc349190532fa616ca1f763ddd6a575858f8885351c72aa2857ad30447c0f6564064187387820d3209e7d38329503ff89f54793300489dec9092007940ff8372222b3e1819c7996a13458f69068855b9f63dec8f9501ab0c799b6190e42edd417740d5a40684bb74946a64c3fe0c1e2f9674f6260e200d7b4913647ebedc75c20d023be90ec8d1eea1a9946143c249e572b5eb6119fa9a2ace5c46f281f9760f8f1769e8104c2441b4da0a5971ff22dd6343591977eb524235e4959804c00a39a43bb31a30024ac801a707c1f8e8983cd5e677b62d9e9ff4e0eaca214a5babda03690229ae91209964242d1acfea5416bc19743dd30c9111a660e3ac4627c4718cfa94c737af2468c52f8e47d9055399c52369b2c550ff62af79b75cb8dba1f538b61d72c5dee5a5ccb44a2f8b70190795942c64602482ec6cf8d74f75cadc921f4050c3e7e52b80cfbc6a29d5024e1de18be732b7c3a1d1eabac8603a8019e378f9a3b5128f8890047363d80be37b9464a213dd61202e7160037f57bb991ef214eb163d796957980177bda87897478e3a4d3094ef2e9a587c991fa4055540ef51a66983aeb2857215af46ea6b3a6d580099434bab327fb680d9097e3072a1637233d0559546e09853f8a6b448e814e7ca6a51482bb2958744692e55b43b8bcd9a5ca487589aaa848e955924169c13d0e95e9348c20c982e0d697a9a5b114708463ebd3b48c5dc7502c1bd3c69bfc97da18c60e1c7b4a4a29528a95bf4b258800208cca3c530a3c05eceb838d61cd56c40e4b41c08
InNoiseEPP = 0080ff1b00fcbf0180000000f8bfffaf00b0ff0a0000300090ff0600ff2f012000f4bf00c0fffbff02000000ffdbff0200ffefffebff0a00ffafff1b00040001c0ff2b00000000400000001400f8effe0b0004000300ff1b00f8bf06c000d0ff0600000000100000c0010000ecfff2bffdef00e0ff02c0fd2f001000f8bf0180ff9b00fcbf0700003000fcbf054000000004000400001c0000c0048000000000000640003000000007400040001000007000f0ff0600ff6fffcbff1200008000200000c00300000c00f3bf07c000100000c0fdef0030000400010000ccff06000030000c00070002c0fffbfffabf0140ff0b000400020000fcffeebfff2f000c00fcbf0300002c00f4bffd6f00b0ff0a00074000c0ff0a0002c0fe0b00f7bf0240001000fcbf00c00020000400030000e0ff0200ff2f00400000c000000100000000020000dcff0e000500000000fcbffc6fff1b000000ff2f0000000c00034000e0ff0e000300ff2b0000000100003c0000000580fe2b0010000380005000f8bf02800000000c00feef00e0ff0e0002c0ff2b000800fd2f0120000400fcefffdbff1200ff2f01e0ff0a000000003c00f8bf0280ffdbff02c0024000f0fffabf0080ff1b000c000100003000fcbf014000d0ff0200003000f0ff0a0000f0ffebff06000240fffbff0200ff2f001000f4bffe2f00ecff06000080ff2b00fcbffbef00e0ffeabf0030000000030000300000000700fe6f0000000300070000f0fffebf040000d0fffebf0000000c000400ff2f00acfff6bf00400100000300feafff0b000400fe6fff3b0014000280000000f4bf0180ff1b000c000300001c00f4bffe6f00d0ff0200fe2f00f0ff02c00240002000040000f000e0fffabffbefff3b0000c0018000000000c00540fffbff0a000400ff2b00080008800010000c00048000100004000340000000f0bf0480002000f4bfffeffe0b000000fcef000000fcbf0000000000080001c0ffdbff060003400010001c00007000e0ff02c00280ff0b000000060000dcfffebf0080fffbff0a00ff2f004000140000300010000400010000bcff0200fe6f003000fcbf0200ff1b00f8bf00b00040000400ff2f000c00180000f00020000800014000000004000180ff0b00fcbffe2f0120001800f76f004000fcbf0100011000100002000100000700fe2f00f0fff2bf018000f0ff0200ffef001000ecbffe2f000000040001c00010001000038000f0ff0e00014000300004000080ff0b0000c00070ff0b0003000180ff0b0004000030003c00e8bf0280ff3b0000c00100010000f3bf00c000200000c00070000000fbbfff2f00bcff0a00004000d0ff06000030000c00f8bf030000300004000030003000080002c0001000000003c0ff0b000000ff6f011000f0bfffafff0b000400004000c0ff0200014001400008000100003c000400fb2f00f0fffebf0100001c0008000500000000f7bf00c0ffcbff0e000400000c00000005c0ff5b0008000100000c00f4bf020000ecfffabf01c0000000fcbffaaf00d0ff02c001000000000700fe2ffe2b00f8bf04c00020000800fdaf0050001400ff6f0000000f0004800000001000000000d0ff02c0fdaf00f0ff0200007000d0fffebf064001e0ff0a0001c0fffbfffebffd2f002c001400fe2f001c0000000600ffebff060004c0ff3b001400fd6f0020000800fe6fff0b000700fb2fff0b00fcbffd2f00f0ff0e0004000110000c0000f000f0ff0200034000100000000140ff3b00fcbf00300100000f00054000d0ff0e000100ff3b00fcbf038000e0fffabf00c0002000fcbffb6f012000fcbf0200000c0003000340ff0b000b00003000ecff0200ff2fff3b0000000080002000f8bffdef00d0fff6bf010000ecff02c00100001c00fcbf01800090000800000000ecfffebffc2f003c00080001c001f0fffebffdaf0000000300feefff0b00f8bf0070001000f4bfff2f00ccfffabfff6f003000000001000110000c00ff2f003c00040001c0ff7b001000034000200000c0ff2f00e0ff1600fc2f00300000c000b0003000180000400150000800fcaf0050000800010000b0ff0e00feef00900000c0fc2f00f0ff02000000002c00080000700000000800007000c0ff06000400000c000b000080fffbff0e000100001c001400fe6f00000007000030000c000f0005c000200000000100005c000800ffaf0030000400ff2f001000f4bf003001500000c000b0ff4b00f4bf0080ff1b00f4bf0300000c00030000b0ffcbfffabf0080ffebff02c003c0fffbff1a00008000000003c0fdef00200000c00040ffbbffeebffdaf010000f4bfff2f002c000000feaf000000fcbffcaf001000040004c0ff0b000b0000800000001300ff2f01100004000100000000ffbf028000d0ff0200feeffedbff0a00fbafffebff020003c0ffebff02c001800060000800fe2f0100000400014001500000c0ff2f01e0ff0200ffef005000f0bf
InRand = 869e8bb1806d746f8978d27fead08f551a3825d1ce8cb7e0f07476ae742b8f82
OutPK = 39d9341741d840b49a1ea42aaa9722c7dee138dd713741b43288ba177ce3c8e5aa59bedf4b449964e0a285205af18e087405025e068f8c0a0393eccaf4cc03081fc982bd9d5e6ca138020b9eb351d787104e9c58bf89f4f2bdbd4c65649308cc3d77eec7b1535d2635596a81b0da909fa26ac5254a6d09bd0d4edb5a797589194d94b3d65022a76e04766e934e91704b98e8b758d0b6f962915d302a7405f9ee58540cbac0b97940f1a3979080b876962a5b113779a60164a42bdfa64f36522516425e285d2fd55af31e0cf29e6e73ae5c991d922811d2d60bf89467458e18b7409e2dd354962123de0804b92a7951ca8ef8c1bdabc4ab0cf118f174af0721200d6241399d4ab35de597e56ba39b0b01215ba6a180467800e02dbe09b2e05760c714085c266ca540f6d872750103cf72918ea6baef8320f8199a2f975484576fd615895d66e4b37697a04e71b79fe92f745013872421ad346d8e5aa5e0548d451d7a0d92a3086f4d52849c84cd8a50ca7199411d91310b17a24523dd274541ea37fc48ab3771b110d76bc10a6fe22060459295a4699c11a0b832c29c3d844e8ab5f3226f04e826005bd0bbac50e7339c51a54a989d204ca1671e15d9531022729f541404840d7ebe90f9e1283e6561d3ed2bb4882a94e5112624e205d0d5eab574e003f24665d3e5b12e2debc982896a00bb6501e79dc887f3ae8352a7262f3fd33543c5f1a1126cbea35beeb09503c927a1de5e131ef644ec508872e143f7f51e47ddeb61105ebda015ef5573e0490c0d887cb676b0816c13c3061ad6a48d6fb3526dc03977a25ba445cd47442b9330f2e92f59efe62560cd6eaf408783a6b2b5744c507b575665bc8a0b80c6d42bbc237b8585a133b5eba767fac0783463c341c6267d082a986410e8a85387f5c48aa415dfd65921ed993ca46bd779219a678f423333d98a4d2f083260ef080b1a87281a6d5c984a59c1d85bb08a5b80af4243b00169c1f59265469f57d603b215f29f2f6dff032e551e0ddf73a6424db8ec1d4d84f48c332895a87be5c18a30629d6045900478db6942878680895223a2bca8195da9fc97e6e08e1a029b5654656a279709890294045beca301eb527625ad22968938235dad6df25de662ee6d687af6f559b809c63bcde4a4a20bedc5bce97264d69c14c462751c9fa4fa4c26054fe0f09a430431c4d63cc787100ac142741849219f0a8a0231fe2070ab87fc95b9596f354acc252ce0b4a00a53fb3e1191f50cabe214bd1ae618e2e83a32308d64ee02475e8b8d8530001804525017f8a9d1c197c903ed14eaf5b76c6418c8395972831be313056ca4759c11e4f9902febad2d2806c6300a6e7664512d68d9543c1090091f2edcd9c65f010313c3e18af7d15745ce168663d094dd6d45750c7094cd5cb6b57289af8c69fe1685840da00e5af305a477ddc150f3799cacb1c34297dc9d64ee255265dc254377220cd410089da86707d48c70b06785a7f113be123887b78af2fa7d9c8c6b292f0a4a0bd7c5a7982c6b3bd638b285300ecce36023dc2c329916b3596db2bbdcec5c8ae5ea1be382bc1520950f9260edc81c58be801574a33769520b2b09d329015e8618f95984c519931c2289ee4e949b29c9460d963c15d2dc488cc864a516f40ba5fab00e154e82054e4dccc3cfc73224589d6fade0f41e63021c9a5b85be53b325a7a311edbc559f565781d0909186dcf6be5869635ef36b110d5e7685ddc33372843fe425ebf5f990d2635280fb01a8bc007057af0c6f995e5d30e316a7ccc4d59243d8760cc930733e7a3972a467f15adaa37e476fd3497a50c905e261fbfa863edce31bf7f95eb5009ac796791e0ed0df86af317cbd6891d939647bfc2c815606ba465658e768fd1e1e5101ef1315481a5ce238885a98b7c2ad689785108fe59f2935328212aa83cac332c93fcb11a1621efa0b0c6d59418e1e460e1af0e3f7198fac9f7c4157c05806906e9a5cea7554255d22af04a631dd85643411b7a5a3ded243b1b3b1a334887a2241f001bf6403a5bdc569858649696a12618444aef605f5df1c13d2da470c513442e4f6b877ca0d163e2981d18c731263a40697d381709a8a25e445ea4b266a84efab42653fc09e246d8ce1acc40fcc0a6ababd28af2a141be523bc713dd7c4c333e9b55f0005c533556b5b07fef3fbce365423ffc3e398638ba10dc30a08ba9301e3cbffd929945e45fae3b41d69e1dde5a59c879f91a9946029b9761f2b641c5c393a95f814cfd806c009a6dbb0e6882c103497fef03e5a1aa152f7c816fd8aaec60b845177e421c510706d40d13a256035294cc0ab0be31e11d5af22235b9187d25964f77ff18ab6e91a3b8bb8731be50d610859020266b065392037db58b77947fe8048656ed0f49665a654a9d1dd681cc94f54d3999951add67369aab6afa00b4e76cfcd5a262b420bd19d189a87c0b8d7c154b5212ed36dcd01b70f540b7b08286ccd4e7a1802ae77115ae829fc7fc0469ce0671c2c
OutRec = 01c000300000000140003000080000000020000c000080000000040001000000000800014000300008000200001000000003c0001000040000c0001000000002c00030000c0003400000000000018000200004000080002000080001c0000000080000c000100000000180000000080001c00020000c000200002000080000c00020000c000340001000080002c0000000040000000000000400014000300000000280000000080000800020000000024000300000000180000000040003c000000004000340001000000002000020000c0001000010000c0000000010000c0000400030000c00014000200000000280002000000002c00020000c0002c000000000000040003000080003c0003000080000c0001000040001c000000004000100002000080003800000000400034000300008000340000000000000000030000800014000000004000380003000000001c0001000000003c000200000000140003000040002c0003000000000000000000c000100003000040003000030000c0002400000000c0000c00000000c0001c0002000080000c000000008000000000000040001800030000000024000200004000140000000040001800030000800024000300000000180000000080003c0002000000000400020000000030000100004000040002000040001c000000008000200001000040000000010000000028000100004000180003000040003c00030000c000080002000000003c00030000c00034000000004000100001000080000c0002000080001000010000c0000c00020000000018000200008000140002000000001c0003000000000c00010000c000000001000040000c0001000040002800010000c00018000100000000140002000080000400020000c0001400020000c0001000000000400020000300000000200001000040000400020000c0001c000200008000140000000000002400000000c000000001000040000c00030000c0002c00010000c000340002000000001800020000000030000200004000080002000080002400030000c000300002000040000c00030000c00028000000000000040003000080001000020000c0002800000000c000240003000080000400030000c000100001000040001400000000800038000300004000180000000000002400020000800014000000004000180001000080002400000000c00038000100004000040001000040003000030000400024000200000000000001000040001800020000c000080001000080003400000000c0000c0000000080002c00010000c0002800020000400014000100004000000000000080000000010000c0002c00030000c00010000100000000000000000040000800020000c0002000000000c0003c00030000c0000400000000c000200001000000001000020000000000000200000000140002000040003c0001000080002c000300000000280000000080001400030000c0001c000100004000380000000000001000010000c0001000000000800038000300008000380003000000003400000000c00020000100008000340000000040000000010000c0002c00030000000024000100004000300000000080000800000000c0003800010000c00014000300004000180002000000000c00020000c000280003000080000c0001000040001c000100000000200003000040001c0003000040003000020000c000000001000080003c0001000040002800000000c00000000000000000200003000080002c00000000c00030000000008000280001000080002c00020000400028000100004000200001000080000c0002000040000c000300004000200001000080003c000200000000000003000000001400030000c000100001000000003000000000c0001800030000000018000100000000000000000080001c0000000080002400010000c00018000200000000000003000040003c0003000000003800000000c000240002000040001000030000c000240002000040003c000200008000000003000040003c0002000000001c0000000000002c0003000040003c0003000040001c00030000000038000200008000340002000080003000000000800030000000008000280000000040000800010000c00008000100000000080003000040001400010000c0000800030000c000300002000040002c0001000000000c0002000040000800020000c000180002000000002c000100008000340003000040002400010000800014000300000000340000000000000400000000c000080002000040002c00000000c000100003000080002c0003000000002800000000000000000100008000300001000040003400000000800004000000000000000001000040002c0003000040000000020000800020000300008000180000000040003c000300004000100001000040002800010000c000140000000080000400020000800
Key = 76f2c93a81a15cc9e46a714d5ede343d56b2e08761c7c8df10b13e08db01ec06
InNoiseS = 4ca10ae48258b14d83e48384f858eae4c130e49055a044c78590f0a74f1a19e8edd427300659bb38647c032c5722a6ac4b05413b4a0dc870ac1b16f25099428b9beb83af39887340a1c4bd986241429eb8eec081442a418b10ac60be94b3e34374a63c5582274aba579a03202666b16f3066985a26b96dd8993e242ccd6a3d9a2d287fdc82da9091830d0886b80bf3419ae968c615521160e85676c96af65dd92ea10e2c520bca4b882326b7b2c131d22d922827c5b41f2f33b281b50e8b64d92ac48a9bc4516a39272018ef5b707223b59bc2e07dd6831015b610b04638aa9d949cb7444c7d3162cf3a088b628f73c93d66375540330ac2d871d4b0405421caa142a0a2effcaacfe5173862deb228da286993d7605db54efd98f122b1949be7a15481fbd23d97d588b7bce9bf4da31481296149138c1b5753caaa9428b6d5f3be48c69979d351525c61532bf5535aa7d72850c294021d1614fda36c781f2ddbf10a4f723e578a596092ec312827ae456cac024c5a44bb68e5175025ce6876aeb1951d022426faab5a0db9d0cf369324a153533fb50b5a5866c77c00524265020b769517d7970918f5d2bc5a6e874332186d5f9e7a3a03aa28a39de5078002c0845c9eb74791088a81b185958e014f95d1219d702d2ec39a772fa82a3c91fc873a991d54c3c0babb64a7bdd15e78232d3b71a1c08bd60e68fc2f5e46348c8b948c1f93860eab88d24b736c785f2a4564a6754492c9c988c786166708d2b240d3da4c3280bd5616c0aff7a81a9a560809766df9b27e014c6c8aa45b38a6416046ba4b560804a90b54c3f5b6a2abaa7149968c8567c0ed07f2ee99218ed52b88bd98624c1c91b9ae1b082b6d07c8697eccc6a953cec576a25cdf548866a1cb03ded4fb26a1afa6c9287050459de64af1aac1572b1509643c6407f5d4a944904856c42f770717adbc701ff3c9f44aae6bea40c50bdd9f1f9368b667286732023d89581e7f872639f19766b65305b07babe9003e631b6a32511e690a864a18d45263c9436a0f1245db4405b31e1d9a6598922ae6f09a61975b3ac27225baa60e1bf6f01b8a0c07988dc9167648e9b1891c3e01a5031260cd52d08cce39498835b9122ef5d4f24f34c7623448294c4da985b5904583bd6f7e301bb911abaf1c778ee1567e8f4df0e05479cf1b5854e0cc7083a4463a96f2aa4d28944147464d249057b13c3eb8e0e93466a70194309f3339ef597459e9ffb5b15a1cf080c34713b819f6051d2baa142b9602460ac3451161913bd960202f68092c456b6ab71c638877f008862904b3fa62b815414e745b2309629d4691e894282c37e70ab15a82a7b055157b481552c6ee3ef7510a9d9420216b7f2275ef64dab95cc86b3e8ffbcaf508bafa0251c4755d287041290b4f6675f22d3ff9c31808c29d8281f2aaa7c7dede72a42592c10b20a35cee60b31b9d67f5ea6adaa33fb3dd911816aa142975551ebd40569bb1fd904a504b7ac811234029921b6b06b28a1df7c2a2ed59a4ad3541f8852e815b08c09444809decfd2904a62d991cc3c6659d6d4c6906d482bc03cce05cbb9ae142264aeda128148084c5b93b831458b061dd99e94e60a1ef51199f550156047901792628c6d5ff316c20be6d5ea59030d6abb624f8909e12a02dcf69f039ad45ffda6113f2f6aa9be6bb934122ae2de84b7a0add8488c052aaf50d0e098d58c7be3c80fe946c566c00b4739fd59aa2de006885b0cb9c65231f5fa760af69a929443aa3252aa16497dcb2c1180f42cca1310b99278a956a07cf540561dc0bb9e8b6b2ea25e57ae52d636b6297a2afbcb6d014942a33ce4869829de6f1ba761b60b6b93f993938884076c1e4976848f8bb6c4486daddaae7fb8073749a70f0eec61ff2c9687184c09bd15f849108700efe8a01b72c9c97d40957b4e3d64533411887541a5de6518ab756994bb5ed9f7af8da0bbe6959c57e4a2f346884a6716a847015c5545d69770d56d44500097f83ee4b736df867029d979848b64a2c281b2ac3d140ed854f12fd946b770754139e0e320223dac9823a14c28cbae29dc4af992ced62ab7255f265c533cb54b75f48a8321e7aa8f7939c468d26645c57b4abf0569260229a40611920af1add758474b8d026f41785559ad04faa501a649e44abee8607fc4eb21376552ba48931156485c7916d4d63247a757d4f92cf34322202b94acdc3276d99a2a899d3471475bb268ef9ea9976a949437e30e168301d027518aeec04ffc4294a00a2649b271b334f3cbdf88678b8b8c583f62c0815937667aede6ae53aec271e5d885a84b58d348449aa06649d6a635bd7d392885a0ae60218d8a085a509f5e5ad12e24c4d36b04600c0011623d4a4bd2206fce8d5003234405db3ad7e3d4dd6aa790abc6b1e49e8b26436ae6c9f1010b1e052158639c1582d641d8b3ed0a9c289aa5eae66e66a43048876b14cf4a69489224564c4932adaaf83e2b15e0b2248425d71198849f534d801b24cccb2aa434829
InPK = 39d9341741d840b49a1ea42aaa9722c7dee138dd713741b43288ba177ce3c8e5aa59bedf4b449964e0a285205af18e087405025e068f8c0a0393eccaf4cc03081fc982bd9d5e6ca138020b9eb351d787104e9c58bf89f4f2bdbd4c65649308cc3d77eec7b1535d2635596a81b0da909fa26ac5254a6d09bd0d4edb5a797589194d94b3d65022a76e04766e934e91704b98e8b758d0b6f962915d302a7405f9ee58540cbac0b97940f1a3979080b876962a5b113779a60164a42bdfa64f36522516425e285d2fd55af31e0cf29e6e73ae5c991d922811d2d60bf89467458e18b7409e2dd354962123de0804b92a7951ca8ef8c1bdabc4ab0cf118f174af0721200d6241399d4ab35de597e56ba39b0b01215ba6a180467800e02dbe09b2e05760c714085c266ca540f6d872750103cf72918ea6baef8320f8199a2f975484576fd615895d66e4b37697a04e71b79fe92f745013872421ad346d8e5aa5e0548d451d7a0d92a3086f4d52849c84cd8a50ca7199411d91310b17a24523dd274541ea37fc48ab3771b110d76bc10a6fe22060459295a4699c11a0b832c29c3d844e8ab5f3226f04e826005bd0bbac50e7339c51a54a989d204ca1671e15d9531022729f541404840d7ebe90f9e1283e6561d3ed2bb4882a94e5112624e205d0d5eab574e003f24665d3e5b12e2debc982896a00bb6501e79dc887f3ae8352a7262f3fd33543c5f1a1126cbea35beeb09503c927a1de5e131ef644ec508872e143f7f51e47ddeb61105ebda015ef5573e0490c0d887cb676b0816c13c3061ad6a48d6fb3526dc03977a25ba445cd47442b9330f2e92f59efe62560cd6eaf408783a6b2b5744c507b575665bc8a0b80c6d42bbc237b8585a133b5eba767fac0783463c341c6267d082a986410e8a85387f5c48aa415dfd65921ed993ca46bd779219a678f423333d98a4d2f083260ef080b1a87281a6d5c984a59c1d85bb08a5b80af4243b00169c1f59265469f57d603b215f29f2f6dff032e551e0ddf73a6424db8ec1d4d84f48c332895a87be5c18a30629d6045900478db6942878680895223a2bca8195da9fc97e6e08e1a029b5654656a279709890294045beca301eb527625ad22968938235dad6df25de662ee6d687af6f559b809c63bcde4a4a20bedc5bce97264d69c14c462751c9fa4fa4c26054fe0f09a430431c4d63cc787100ac142741849219f0a8a0231fe2070ab87fc95b9596f354acc252ce0b4a00a53fb3e1191f50cabe214bd1ae618e2e83a32308d64ee02475e8b8d8530001804525017f8a9d1c197c903ed14eaf5b76c6418c8395972831be313056ca4759c11e4f9902febad2d2806c6300a6e7664512d68d9543c1090091f2edcd9c65f010313c3e18af7d15745ce168663d094dd6d45750c7094cd5cb6b57289af8c69fe1685840da00e5af305a477ddc150f3799cacb1c34297dc9d64ee255265dc254377220cd410089da86707d48c70b06785a7f113be123887b78af2fa7d9c8c6b292f0a4a0bd7c5a7982c6b3bd638b285300ecce36023dc2c329916b3596db2bbdcec5c8ae5ea1be382bc1520950f9260edc81c58be801574a33769520b2b09d329015e8618f95984c519931c2289ee4e949b29c9460d963c15d2dc488cc864a516f40ba5fab00e154e82054e4dccc3cfc73224589d6fade0f41e63021c9a5b85be53b325a7a311edbc559f565781d0909186dcf6be5869635ef36b110d5e7685ddc33372843fe425ebf5f990d2635280fb01a8bc007057af0c6f995e5d30e316a7ccc4d59243d8760cc930733e7a3972a467f15adaa37e476fd3497a50c905e261fbfa863edce31bf7f95eb5009ac796791e0ed0df86af317cbd6891d939647bfc2c815606ba465658e768fd1e1e5101ef1315481a5ce238885a98b7c2ad689785108fe59f2935328212aa83cac332c93fcb11a1621efa0b0c6d59418e1e460e1af0e3f7198fac9f7c4157c05806906e9a5cea7554255d22af04a631dd85643411b7a5a3ded243b1b3b1a334887a2241f001bf6403a5bdc569858649696a12618444aef605f5df1c13d2da470c513442e4f6b877ca0d163e2981d18c731263a40697d381709a8a25e445ea4b266a84efab42653fc09e246d8ce1acc40fcc0a6ababd28af2a141be523bc713dd7c4c333e9b55f0005c533556b5b07fef3fbce365423ffc3e398638ba10dc30a08ba9301e3cbffd929945e45fae3b41d69e1dde5a59c879f91a9946029b9761f2b641c5c393a95f814cfd806c009a6dbb0e6882c103497fef03e5a1aa152f7c816fd8aaec60b845177e421c510706d40d13a256035294cc0ab0be31e11d5af22235b9187d25964f77ff18ab6e91a3b8bb8731be50d610859020266b065392037db58b77947fe8048656ed0f49665a654a9d1dd681cc94f54d3999951add67369aab6afa00b4e76cfcd5a262b420bd19d189a87c0b8d7c154b5212ed36dcd01b70f540b7b08286ccd4e7a1802ae77115ae829fc7fc0469ce0671c2c
InRec = 01c000300000000140003000080000000020000c000080000000040001000000000800014000300008000200001000000003c0001000040000c0001000000002c00030000c0003400000000000018000200004000080002000080001c0000000080000c000100000000180000000080001c00020000c000200002000080000c00020000c000340001000080002c0000000040000000000000400014000300000000280000000080000800020000000024000300000000180000000040003c000000004000340001000000002000020000c0001000010000c0000000010000c0000400030000c00014000200000000280002000000002c00020000c0002c000000000000040003000080003c0003000080000c0001000040001c000000004000100002000080003800000000400034000300008000340000000000000000030000800014000000004000380003000000001c0001000000003c000200000000140003000040002c0003000000000000000000c000100003000040003000030000c0002400000000c0000c00000000c0001c0002000080000c000000008000000000000040001800030000000024000200004000140000000040001800030000800024000300000000180000000080003c0002000000000400020000000030000100004000040002000040001c000000008000200001000040000000010000000028000100004000180003000040003c00030000c000080002000000003c00030000c00034000000004000100001000080000c0002000080001000010000c0000c00020000000018000200008000140002000000001c0003000000000c00010000c000000001000040000c0001000040002800010000c00018000100000000140002000080000400020000c0001400020000c0001000000000400020000300000000200001000040000400020000c0001c000200008000140000000000002400000000c000000001000040000c00030000c0002c00010000c000340002000000001800020000000030000200004000080002000080002400030000c000300002000040000c00030000c00028000000000000040003000080001000020000c0002800000000c000240003000080000400030000c000100001000040001400000000800038000300004000180000000000002400020000800014000000004000180001000080002400000000c00038000100004000040001000040003000030000400024000200000000000001000040001800020000c000080001000080003400000000c0000c0000000080002c00010000c0002800020000400014000100004000000000000080000000010000c0002c00030000c00010000100000000000000000040000800020000c0002000000000c0003c00030000c0000400000000c000200001000000001000020000000000000200000000140002000040003c0001000080002c000300000000280000000080001400030000c0001c000100004000380000000000001000010000c0001000000000800038000300008000380003000000003400000000c00020000100008000340000000040000000010000c0002c00030000000024000100004000300000000080000800000000c0003800010000c00014000300004000180002000000000c00020000c000280003000080000c0001000040001c000100000000200003000040001c0003000040003000020000c000000001000080003c0001000040002800000000c00000000000000000200003000080002c00000000c00030000000008000280001000080002c00020000400028000100004000200001000080000c0002000040000c000300004000200001000080003c000200000000000003000000001400030000c000100001000000003000000000c0001800030000000018000100000000000000000080001c0000000080002400010000c00018000200000000000003000040003c0003000000003800000000c000240002000040001000030000c000240002000040003c000200008000000003000040003c0002000000001c0000000000002c0003000040003c0003000040001c00030000000038000200008000340002000080003000000000800030000000008000280000000040000800010000c00008000100000000080003000040001400010000c0000800030000c000300002000040002c0001000000000c0002000040000800020000c000180002000000002c000100008000340003000040002400010000800014000300000000340000000000000400000000c000080002000040002c00000000c000100003000080002c0003000000002800000000000000000100008000300001000040003400000000800004000000000000000001000040002c0003000040000000020000800020000300008000180000000040003c000300004000100001000040002800010000c000140000000080000400020000800
Key = 76f2c93a81a15cc9e46a714d5ede343d56b2e08761c7c8df10b13e08db01ec06
+122
View File
@@ -0,0 +1,122 @@
/* Copyright (c) 2016, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <openssl/crypto.h>
#include <openssl/rand.h>
#include "../test/file_test.h"
#include "../test/scoped_types.h"
#include "internal.h"
static bool TestNewhope(FileTest *t, void *arg) {
ScopedNEWHOPE_POLY a(NEWHOPE_POLY_new());
ScopedNEWHOPE_POLY s(NEWHOPE_POLY_new()), sp(NEWHOPE_POLY_new());
ScopedNEWHOPE_POLY e(NEWHOPE_POLY_new()), ep(NEWHOPE_POLY_new()),
epp(NEWHOPE_POLY_new());
ScopedNEWHOPE_POLY in_pk(NEWHOPE_POLY_new());
ScopedNEWHOPE_POLY in_rec(NEWHOPE_POLY_new());
if (t->GetType() == "InRandA") {
std::vector<uint8_t> a_bytes, s_bytes, e_bytes, expected_pk;
if (!t->GetBytes(&a_bytes, "InRandA") ||
!t->GetBytes(&s_bytes, "InNoiseS") ||
!t->GetBytes(&e_bytes, "InNoiseE") ||
!t->GetBytes(&expected_pk, "OutPK")) {
return false;
}
NEWHOPE_POLY_frombytes(a.get(), a_bytes.data());
NEWHOPE_POLY_frombytes(s.get(), s_bytes.data());
NEWHOPE_POLY_frombytes(e.get(), e_bytes.data());
NEWHOPE_POLY pk;
NEWHOPE_offer_computation(&pk, s.get(), e.get(), a.get());
uint8_t pk_bytes[NEWHOPE_POLY_LENGTH];
NEWHOPE_POLY_tobytes(pk_bytes, &pk);
return t->ExpectBytesEqual(expected_pk.data(), expected_pk.size(),
pk_bytes, NEWHOPE_POLY_LENGTH);
} else if (t->GetType() == "InPK") {
std::vector<uint8_t> rand, in_pk_bytes, a_bytes, sp_bytes, ep_bytes,
epp_bytes, expected_pk, expected_rec, expected_key;
if (!t->GetBytes(&in_pk_bytes, "InPK") ||
!t->GetBytes(&rand, "InRand") ||
!t->GetBytes(&a_bytes, "InA") ||
!t->GetBytes(&sp_bytes, "InNoiseSP") ||
!t->GetBytes(&ep_bytes, "InNoiseEP") ||
!t->GetBytes(&epp_bytes, "InNoiseEPP") ||
!t->GetBytes(&expected_pk, "OutPK") ||
!t->GetBytes(&expected_rec, "OutRec") ||
!t->GetBytes(&expected_key, "Key")) {
return false;
}
NEWHOPE_POLY_frombytes(in_pk.get(), in_pk_bytes.data());
NEWHOPE_POLY_frombytes(a.get(), a_bytes.data());
NEWHOPE_POLY_frombytes(sp.get(), sp_bytes.data());
NEWHOPE_POLY_frombytes(ep.get(), ep_bytes.data());
NEWHOPE_POLY_frombytes(epp.get(), epp_bytes.data());
uint8_t key[NEWHOPE_KEY_LENGTH];
NEWHOPE_POLY pk, rec;
NEWHOPE_accept_computation(key, &pk, &rec,
sp.get(), ep.get(), epp.get(),
rand.data(), in_pk.get(), a.get());
uint8_t pk_bytes[NEWHOPE_POLY_LENGTH], rec_bytes[NEWHOPE_POLY_LENGTH];
NEWHOPE_POLY_tobytes(pk_bytes, &pk);
NEWHOPE_POLY_tobytes(rec_bytes, &rec);
return
t->ExpectBytesEqual(expected_key.data(), expected_key.size(),
key, NEWHOPE_KEY_LENGTH) &&
t->ExpectBytesEqual(expected_pk.data(), expected_pk.size(),
pk_bytes, NEWHOPE_POLY_LENGTH) &&
t->ExpectBytesEqual(expected_rec.data(), expected_rec.size(),
rec_bytes, NEWHOPE_POLY_LENGTH);
} else if (t->GetType() == "InNoiseS") {
std::vector<uint8_t> s_bytes, in_pk_bytes, in_rec_bytes, expected_key;
if (!t->GetBytes(&s_bytes, "InNoiseS") ||
!t->GetBytes(&in_pk_bytes, "InPK") ||
!t->GetBytes(&in_rec_bytes, "InRec") ||
!t->GetBytes(&expected_key, "Key")) {
return false;
}
NEWHOPE_POLY_frombytes(s.get(), s_bytes.data());
NEWHOPE_POLY_frombytes(in_pk.get(), in_pk_bytes.data());
NEWHOPE_POLY_frombytes(in_rec.get(), in_rec_bytes.data());
uint8_t key[NEWHOPE_KEY_LENGTH];
NEWHOPE_finish_computation(key, s.get(), in_pk.get(), in_rec.get());
return t->ExpectBytesEqual(expected_key.data(), expected_key.size(), key,
NEWHOPE_KEY_LENGTH);
} else {
t->PrintLine("Unknown test '%s'", t->GetType().c_str());
return false;
}
}
int main(int argc, char **argv) {
CRYPTO_library_init();
if (argc != 2) {
fprintf(stderr, "%s <test file>\n", argv[0]);
return 1;
}
return FileTestMain(TestNewhope, nullptr, argv[1]);
}
+148
View File
@@ -0,0 +1,148 @@
/* Copyright (c) 2016, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include "internal.h"
static uint16_t bitrev_table[1024] = {
0, 512, 256, 768, 128, 640, 384, 896, 64, 576, 320, 832, 192, 704,
448, 960, 32, 544, 288, 800, 160, 672, 416, 928, 96, 608, 352, 864,
224, 736, 480, 992, 16, 528, 272, 784, 144, 656, 400, 912, 80, 592,
336, 848, 208, 720, 464, 976, 48, 560, 304, 816, 176, 688, 432, 944,
112, 624, 368, 880, 240, 752, 496, 1008, 8, 520, 264, 776, 136, 648,
392, 904, 72, 584, 328, 840, 200, 712, 456, 968, 40, 552, 296, 808,
168, 680, 424, 936, 104, 616, 360, 872, 232, 744, 488, 1000, 24, 536,
280, 792, 152, 664, 408, 920, 88, 600, 344, 856, 216, 728, 472, 984,
56, 568, 312, 824, 184, 696, 440, 952, 120, 632, 376, 888, 248, 760,
504, 1016, 4, 516, 260, 772, 132, 644, 388, 900, 68, 580, 324, 836,
196, 708, 452, 964, 36, 548, 292, 804, 164, 676, 420, 932, 100, 612,
356, 868, 228, 740, 484, 996, 20, 532, 276, 788, 148, 660, 404, 916,
84, 596, 340, 852, 212, 724, 468, 980, 52, 564, 308, 820, 180, 692,
436, 948, 116, 628, 372, 884, 244, 756, 500, 1012, 12, 524, 268, 780,
140, 652, 396, 908, 76, 588, 332, 844, 204, 716, 460, 972, 44, 556,
300, 812, 172, 684, 428, 940, 108, 620, 364, 876, 236, 748, 492, 1004,
28, 540, 284, 796, 156, 668, 412, 924, 92, 604, 348, 860, 220, 732,
476, 988, 60, 572, 316, 828, 188, 700, 444, 956, 124, 636, 380, 892,
252, 764, 508, 1020, 2, 514, 258, 770, 130, 642, 386, 898, 66, 578,
322, 834, 194, 706, 450, 962, 34, 546, 290, 802, 162, 674, 418, 930,
98, 610, 354, 866, 226, 738, 482, 994, 18, 530, 274, 786, 146, 658,
402, 914, 82, 594, 338, 850, 210, 722, 466, 978, 50, 562, 306, 818,
178, 690, 434, 946, 114, 626, 370, 882, 242, 754, 498, 1010, 10, 522,
266, 778, 138, 650, 394, 906, 74, 586, 330, 842, 202, 714, 458, 970,
42, 554, 298, 810, 170, 682, 426, 938, 106, 618, 362, 874, 234, 746,
490, 1002, 26, 538, 282, 794, 154, 666, 410, 922, 90, 602, 346, 858,
218, 730, 474, 986, 58, 570, 314, 826, 186, 698, 442, 954, 122, 634,
378, 890, 250, 762, 506, 1018, 6, 518, 262, 774, 134, 646, 390, 902,
70, 582, 326, 838, 198, 710, 454, 966, 38, 550, 294, 806, 166, 678,
422, 934, 102, 614, 358, 870, 230, 742, 486, 998, 22, 534, 278, 790,
150, 662, 406, 918, 86, 598, 342, 854, 214, 726, 470, 982, 54, 566,
310, 822, 182, 694, 438, 950, 118, 630, 374, 886, 246, 758, 502, 1014,
14, 526, 270, 782, 142, 654, 398, 910, 78, 590, 334, 846, 206, 718,
462, 974, 46, 558, 302, 814, 174, 686, 430, 942, 110, 622, 366, 878,
238, 750, 494, 1006, 30, 542, 286, 798, 158, 670, 414, 926, 94, 606,
350, 862, 222, 734, 478, 990, 62, 574, 318, 830, 190, 702, 446, 958,
126, 638, 382, 894, 254, 766, 510, 1022, 1, 513, 257, 769, 129, 641,
385, 897, 65, 577, 321, 833, 193, 705, 449, 961, 33, 545, 289, 801,
161, 673, 417, 929, 97, 609, 353, 865, 225, 737, 481, 993, 17, 529,
273, 785, 145, 657, 401, 913, 81, 593, 337, 849, 209, 721, 465, 977,
49, 561, 305, 817, 177, 689, 433, 945, 113, 625, 369, 881, 241, 753,
497, 1009, 9, 521, 265, 777, 137, 649, 393, 905, 73, 585, 329, 841,
201, 713, 457, 969, 41, 553, 297, 809, 169, 681, 425, 937, 105, 617,
361, 873, 233, 745, 489, 1001, 25, 537, 281, 793, 153, 665, 409, 921,
89, 601, 345, 857, 217, 729, 473, 985, 57, 569, 313, 825, 185, 697,
441, 953, 121, 633, 377, 889, 249, 761, 505, 1017, 5, 517, 261, 773,
133, 645, 389, 901, 69, 581, 325, 837, 197, 709, 453, 965, 37, 549,
293, 805, 165, 677, 421, 933, 101, 613, 357, 869, 229, 741, 485, 997,
21, 533, 277, 789, 149, 661, 405, 917, 85, 597, 341, 853, 213, 725,
469, 981, 53, 565, 309, 821, 181, 693, 437, 949, 117, 629, 373, 885,
245, 757, 501, 1013, 13, 525, 269, 781, 141, 653, 397, 909, 77, 589,
333, 845, 205, 717, 461, 973, 45, 557, 301, 813, 173, 685, 429, 941,
109, 621, 365, 877, 237, 749, 493, 1005, 29, 541, 285, 797, 157, 669,
413, 925, 93, 605, 349, 861, 221, 733, 477, 989, 61, 573, 317, 829,
189, 701, 445, 957, 125, 637, 381, 893, 253, 765, 509, 1021, 3, 515,
259, 771, 131, 643, 387, 899, 67, 579, 323, 835, 195, 707, 451, 963,
35, 547, 291, 803, 163, 675, 419, 931, 99, 611, 355, 867, 227, 739,
483, 995, 19, 531, 275, 787, 147, 659, 403, 915, 83, 595, 339, 851,
211, 723, 467, 979, 51, 563, 307, 819, 179, 691, 435, 947, 115, 627,
371, 883, 243, 755, 499, 1011, 11, 523, 267, 779, 139, 651, 395, 907,
75, 587, 331, 843, 203, 715, 459, 971, 43, 555, 299, 811, 171, 683,
427, 939, 107, 619, 363, 875, 235, 747, 491, 1003, 27, 539, 283, 795,
155, 667, 411, 923, 91, 603, 347, 859, 219, 731, 475, 987, 59, 571,
315, 827, 187, 699, 443, 955, 123, 635, 379, 891, 251, 763, 507, 1019,
7, 519, 263, 775, 135, 647, 391, 903, 71, 583, 327, 839, 199, 711,
455, 967, 39, 551, 295, 807, 167, 679, 423, 935, 103, 615, 359, 871,
231, 743, 487, 999, 23, 535, 279, 791, 151, 663, 407, 919, 87, 599,
343, 855, 215, 727, 471, 983, 55, 567, 311, 823, 183, 695, 439, 951,
119, 631, 375, 887, 247, 759, 503, 1015, 15, 527, 271, 783, 143, 655,
399, 911, 79, 591, 335, 847, 207, 719, 463, 975, 47, 559, 303, 815,
175, 687, 431, 943, 111, 623, 367, 879, 239, 751, 495, 1007, 31, 543,
287, 799, 159, 671, 415, 927, 95, 607, 351, 863, 223, 735, 479, 991,
63, 575, 319, 831, 191, 703, 447, 959, 127, 639, 383, 895, 255, 767,
511, 1023};
void newhope_bitrev_vector(uint16_t* poly) {
unsigned int i, r;
uint16_t tmp;
for (i = 0; i < PARAM_N; i++) {
r = bitrev_table[i];
if (i < r) {
tmp = poly[i];
poly[i] = poly[r];
poly[r] = tmp;
}
}
}
void newhope_mul_coefficients(uint16_t* poly, const uint16_t* factors) {
unsigned int i;
for (i = 0; i < PARAM_N; i++) {
poly[i] = newhope_montgomery_reduce((poly[i] * factors[i]));
}
}
/* GS_bo_to_no; omegas need to be in Montgomery domain */
void newhope_ntt(uint16_t* a, const uint16_t* omega) {
int i, start, j, jTwiddle, distance;
uint16_t temp, W;
for (i = 0; i < 10; i += 2) {
/* Even level */
distance = (1 << i);
for (start = 0; start < distance; start++) {
jTwiddle = 0;
for (j = start; j < PARAM_N - 1; j += 2 * distance) {
W = omega[jTwiddle++];
temp = a[j];
a[j] = (temp + a[j + distance]); /* Omit reduction (be lazy) */
a[j + distance] = newhope_montgomery_reduce(
(W * ((uint32_t)temp + 3 * PARAM_Q - a[j + distance])));
}
}
/* Odd level */
distance <<= 1;
for (start = 0; start < distance; start++) {
jTwiddle = 0;
for (j = start; j < PARAM_N - 1; j += 2 * distance) {
W = omega[jTwiddle++];
temp = a[j];
a[j] = newhope_barrett_reduce((temp + a[j + distance]));
a[j + distance] = newhope_montgomery_reduce(
(W * ((uint32_t)temp + 3 * PARAM_Q - a[j + distance])));
}
}
}
}
+189
View File
@@ -0,0 +1,189 @@
/* Copyright (c) 2016, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include <assert.h>
#include <string.h>
#include <openssl/aes.h>
#include <openssl/rand.h>
#include "internal.h"
extern uint16_t newhope_omegas_montgomery[];
extern uint16_t newhope_omegas_inv_montgomery[];
extern uint16_t newhope_psis_bitrev_montgomery[];
extern uint16_t newhope_psis_inv_montgomery[];
void NEWHOPE_POLY_frombytes(NEWHOPE_POLY* r, const uint8_t* a) {
int i;
for (i = 0; i < PARAM_N / 4; i++) {
r->coeffs[4 * i + 0] =
a[7 * i + 0] | (((uint16_t)a[7 * i + 1] & 0x3f) << 8);
r->coeffs[4 * i + 1] = (a[7 * i + 1] >> 6) |
(((uint16_t)a[7 * i + 2]) << 2) |
(((uint16_t)a[7 * i + 3] & 0x0f) << 10);
r->coeffs[4 * i + 2] = (a[7 * i + 3] >> 4) |
(((uint16_t)a[7 * i + 4]) << 4) |
(((uint16_t)a[7 * i + 5] & 0x03) << 12);
r->coeffs[4 * i + 3] =
(a[7 * i + 5] >> 2) | (((uint16_t)a[7 * i + 6]) << 6);
}
}
void NEWHOPE_POLY_tobytes(uint8_t* r, const NEWHOPE_POLY* p) {
int i;
uint16_t t0, t1, t2, t3, m;
int16_t c;
for (i = 0; i < PARAM_N / 4; i++) {
t0 = newhope_barrett_reduce(
p->coeffs[4 * i + 0]); /* Make sure that coefficients
have only 14 bits */
t1 = newhope_barrett_reduce(p->coeffs[4 * i + 1]);
t2 = newhope_barrett_reduce(p->coeffs[4 * i + 2]);
t3 = newhope_barrett_reduce(p->coeffs[4 * i + 3]);
m = t0 - PARAM_Q;
c = m;
c >>= 15;
t0 = m ^ ((t0 ^ m) & c); /* Make sure that coefficients are in [0,q] */
m = t1 - PARAM_Q;
c = m;
c >>= 15;
t1 = m ^ ((t1 ^ m) & c); /* <Make sure that coefficients are in [0,q] */
m = t2 - PARAM_Q;
c = m;
c >>= 15;
t2 = m ^ ((t2 ^ m) & c); /* <Make sure that coefficients are in [0,q] */
m = t3 - PARAM_Q;
c = m;
c >>= 15;
t3 = m ^ ((t3 ^ m) & c); /* Make sure that coefficients are in [0,q] */
r[7 * i + 0] = t0 & 0xff;
r[7 * i + 1] = (t0 >> 8) | (t1 << 6);
r[7 * i + 2] = (t1 >> 2);
r[7 * i + 3] = (t1 >> 10) | (t2 << 4);
r[7 * i + 4] = (t2 >> 4);
r[7 * i + 5] = (t2 >> 12) | (t3 << 2);
r[7 * i + 6] = (t3 >> 6);
}
}
void newhope_poly_uniform(NEWHOPE_POLY* a, const uint8_t* seed) {
/* The reference implementation uses SHAKE-128 here; this implementation uses
* AES-CTR. Use half the seed for the initialization vector and half for the
* key. */
#if SEED_LENGTH != 2 * AES_BLOCK_SIZE
#error "2 * seed length != AES_BLOCK_SIZE"
#endif
uint8_t ivec[AES_BLOCK_SIZE];
memcpy(ivec, &seed[SEED_LENGTH / 2], SEED_LENGTH / 2);
AES_KEY key;
AES_set_encrypt_key(seed, 8 * SEED_LENGTH / 2, &key);
/* AES state. */
uint8_t ecount[AES_BLOCK_SIZE];
memset(ecount, 0, AES_BLOCK_SIZE);
/* Encrypt a block of zeros just to get the random bytes. With luck, 2688
* bytes is enough. */
uint8_t buf[AES_BLOCK_SIZE * 168];
memset(buf, 0, sizeof(buf));
unsigned int block_num = 0;
AES_ctr128_encrypt(buf, buf, sizeof(buf), &key, ivec, ecount, &block_num);
size_t pos = 0, coeff_num = 0;
while (coeff_num < PARAM_N) {
/* Specialized for q = 12889 */
uint16_t val = (buf[pos] | ((uint16_t)buf[pos + 1] << 8)) & 0x3fff;
if (val < PARAM_Q) {
a->coeffs[coeff_num++] = val;
}
pos += 2;
if (pos > sizeof(buf) - 2) {
memset(buf, 0, sizeof(buf));
AES_ctr128_encrypt(buf, buf, sizeof(buf), &key, ivec, ecount, &block_num);
pos = 0;
}
}
}
void NEWHOPE_POLY_noise(NEWHOPE_POLY* r) {
#if PARAM_K != 16
#error "poly_getnoise in poly.c only supports k=16"
#endif
uint32_t tp[PARAM_N];
/* The reference implementation calls ChaCha20 here. */
RAND_bytes((uint8_t *) tp, sizeof(tp));
size_t i;
for (i = 0; i < PARAM_N; i++) {
const uint32_t t = tp[i];
size_t j;
uint32_t d = 0;
for (j = 0; j < 8; j++) {
d += (t >> j) & 0x01010101;
}
const uint32_t a = ((d >> 8) & 0xff) + (d & 0xff);
const uint32_t b = (d >> 24) + ((d >> 16) & 0xff);
r->coeffs[i] = a + PARAM_Q - b;
}
}
void newhope_poly_pointwise(NEWHOPE_POLY* r, const NEWHOPE_POLY* a,
const NEWHOPE_POLY* b) {
size_t i;
for (i = 0; i < PARAM_N; i++) {
uint16_t t = newhope_montgomery_reduce(3186 * b->coeffs[i]);
/* t is now in Montgomery domain */
r->coeffs[i] = newhope_montgomery_reduce(a->coeffs[i] * t);
/* r->coeffs[i] is back in normal domain */
}
}
void newhope_poly_add(NEWHOPE_POLY* r, const NEWHOPE_POLY* a,
const NEWHOPE_POLY* b) {
size_t i;
for (i = 0; i < PARAM_N; i++) {
r->coeffs[i] = newhope_barrett_reduce(a->coeffs[i] + b->coeffs[i]);
}
}
void NEWHOPE_POLY_noise_ntt(NEWHOPE_POLY* r) {
NEWHOPE_POLY_noise(r);
/* Forward NTT transformation. Because we're operating on a noise polynomial,
* we can regard the bits as already reversed and skip the bit-reversal
* step:
*
* newhope_bitrev_vector(r->coeffs); */
newhope_mul_coefficients(r->coeffs, newhope_psis_bitrev_montgomery);
newhope_ntt((uint16_t *) r->coeffs, newhope_omegas_montgomery);
}
void newhope_poly_invntt(NEWHOPE_POLY* r) {
newhope_bitrev_vector(r->coeffs);
newhope_ntt((uint16_t *) r->coeffs, newhope_omegas_inv_montgomery);
newhope_mul_coefficients(r->coeffs, newhope_psis_inv_montgomery);
}
+306
View File
@@ -0,0 +1,306 @@
/* Copyright (c) 2016, Google Inc.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
#include "internal.h"
uint16_t newhope_omegas_montgomery[PARAM_N / 2] = {
4075, 6974, 7373, 7965, 3262, 5079, 522, 2169, 6364, 1018, 1041,
8775, 2344, 11011, 5574, 1973, 4536, 1050, 6844, 3860, 3818, 6118,
2683, 1190, 4789, 7822, 7540, 6752, 5456, 4449, 3789, 12142, 11973,
382, 3988, 468, 6843, 5339, 6196, 3710, 11316, 1254, 5435, 10930,
3998, 10256, 10367, 3879, 11889, 1728, 6137, 4948, 5862, 6136, 3643,
6874, 8724, 654, 10302, 1702, 7083, 6760, 56, 3199, 9987, 605,
11785, 8076, 5594, 9260, 6403, 4782, 6212, 4624, 9026, 8689, 4080,
11868, 6221, 3602, 975, 8077, 8851, 9445, 5681, 3477, 1105, 142,
241, 12231, 1003, 3532, 5009, 1956, 6008, 11404, 7377, 2049, 10968,
12097, 7591, 5057, 3445, 4780, 2920, 7048, 3127, 8120, 11279, 6821,
11502, 8807, 12138, 2127, 2839, 3957, 431, 1579, 6383, 9784, 5874,
677, 3336, 6234, 2766, 1323, 9115, 12237, 2031, 6956, 6413, 2281,
3969, 3991, 12133, 9522, 4737, 10996, 4774, 5429, 11871, 3772, 453,
5908, 2882, 1805, 2051, 1954, 11713, 3963, 2447, 6142, 8174, 3030,
1843, 2361, 12071, 2908, 3529, 3434, 3202, 7796, 2057, 5369, 11939,
1512, 6906, 10474, 11026, 49, 10806, 5915, 1489, 9789, 5942, 10706,
10431, 7535, 426, 8974, 3757, 10314, 9364, 347, 5868, 9551, 9634,
6554, 10596, 9280, 11566, 174, 2948, 2503, 6507, 10723, 11606, 2459,
64, 3656, 8455, 5257, 5919, 7856, 1747, 9166, 5486, 9235, 6065,
835, 3570, 4240, 11580, 4046, 10970, 9139, 1058, 8210, 11848, 922,
7967, 1958, 10211, 1112, 3728, 4049, 11130, 5990, 1404, 325, 948,
11143, 6190, 295, 11637, 5766, 8212, 8273, 2919, 8527, 6119, 6992,
8333, 1360, 2555, 6167, 1200, 7105, 7991, 3329, 9597, 12121, 5106,
5961, 10695, 10327, 3051, 9923, 4896, 9326, 81, 3091, 1000, 7969,
4611, 726, 1853, 12149, 4255, 11112, 2768, 10654, 1062, 2294, 3553,
4805, 2747, 4846, 8577, 9154, 1170, 2319, 790, 11334, 9275, 9088,
1326, 5086, 9094, 6429, 11077, 10643, 3504, 3542, 8668, 9744, 1479,
1, 8246, 7143, 11567, 10984, 4134, 5736, 4978, 10938, 5777, 8961,
4591, 5728, 6461, 5023, 9650, 7468, 949, 9664, 2975, 11726, 2744,
9283, 10092, 5067, 12171, 2476, 3748, 11336, 6522, 827, 9452, 5374,
12159, 7935, 3296, 3949, 9893, 4452, 10908, 2525, 3584, 8112, 8011,
10616, 4989, 6958, 11809, 9447, 12280, 1022, 11950, 9821, 11745, 5791,
5092, 2089, 9005, 2881, 3289, 2013, 9048, 729, 7901, 1260, 5755,
4632, 11955, 2426, 10593, 1428, 4890, 5911, 3932, 9558, 8830, 3637,
5542, 145, 5179, 8595, 3707, 10530, 355, 3382, 4231, 9741, 1207,
9041, 7012, 1168, 10146, 11224, 4645, 11885, 10911, 10377, 435, 7952,
4096, 493, 9908, 6845, 6039, 2422, 2187, 9723, 8643, 9852, 9302,
6022, 7278, 1002, 4284, 5088, 1607, 7313, 875, 8509, 9430, 1045,
2481, 5012, 7428, 354, 6591, 9377, 11847, 2401, 1067, 7188, 11516,
390, 8511, 8456, 7270, 545, 8585, 9611, 12047, 1537, 4143, 4714,
4885, 1017, 5084, 1632, 3066, 27, 1440, 8526, 9273, 12046, 11618,
9289, 3400, 9890, 3136, 7098, 8758, 11813, 7384, 3985, 11869, 6730,
10745, 10111, 2249, 4048, 2884, 11136, 2126, 1630, 9103, 5407, 2686,
9042, 2969, 8311, 9424, 9919, 8779, 5332, 10626, 1777, 4654, 10863,
7351, 3636, 9585, 5291, 8374, 2166, 4919, 12176, 9140, 12129, 7852,
12286, 4895, 10805, 2780, 5195, 2305, 7247, 9644, 4053, 10600, 3364,
3271, 4057, 4414, 9442, 7917, 2174};
uint16_t newhope_omegas_inv_montgomery[PARAM_N / 2] = {
4075, 5315, 4324, 4916, 10120, 11767, 7210, 9027, 10316, 6715, 1278,
9945, 3514, 11248, 11271, 5925, 147, 8500, 7840, 6833, 5537, 4749,
4467, 7500, 11099, 9606, 6171, 8471, 8429, 5445, 11239, 7753, 9090,
12233, 5529, 5206, 10587, 1987, 11635, 3565, 5415, 8646, 6153, 6427,
7341, 6152, 10561, 400, 8410, 1922, 2033, 8291, 1359, 6854, 11035,
973, 8579, 6093, 6950, 5446, 11821, 8301, 11907, 316, 52, 3174,
10966, 9523, 6055, 8953, 11612, 6415, 2505, 5906, 10710, 11858, 8332,
9450, 10162, 151, 3482, 787, 5468, 1010, 4169, 9162, 5241, 9369,
7509, 8844, 7232, 4698, 192, 1321, 10240, 4912, 885, 6281, 10333,
7280, 8757, 11286, 58, 12048, 12147, 11184, 8812, 6608, 2844, 3438,
4212, 11314, 8687, 6068, 421, 8209, 3600, 3263, 7665, 6077, 7507,
5886, 3029, 6695, 4213, 504, 11684, 2302, 1962, 1594, 6328, 7183,
168, 2692, 8960, 4298, 5184, 11089, 6122, 9734, 10929, 3956, 5297,
6170, 3762, 9370, 4016, 4077, 6523, 652, 11994, 6099, 1146, 11341,
11964, 10885, 6299, 1159, 8240, 8561, 11177, 2078, 10331, 4322, 11367,
441, 4079, 11231, 3150, 1319, 8243, 709, 8049, 8719, 11454, 6224,
3054, 6803, 3123, 10542, 4433, 6370, 7032, 3834, 8633, 12225, 9830,
683, 1566, 5782, 9786, 9341, 12115, 723, 3009, 1693, 5735, 2655,
2738, 6421, 11942, 2925, 1975, 8532, 3315, 11863, 4754, 1858, 1583,
6347, 2500, 10800, 6374, 1483, 12240, 1263, 1815, 5383, 10777, 350,
6920, 10232, 4493, 9087, 8855, 8760, 9381, 218, 9928, 10446, 9259,
4115, 6147, 9842, 8326, 576, 10335, 10238, 10484, 9407, 6381, 11836,
8517, 418, 6860, 7515, 1293, 7552, 2767, 156, 8298, 8320, 10008,
5876, 5333, 10258, 10115, 4372, 2847, 7875, 8232, 9018, 8925, 1689,
8236, 2645, 5042, 9984, 7094, 9509, 1484, 7394, 3, 4437, 160,
3149, 113, 7370, 10123, 3915, 6998, 2704, 8653, 4938, 1426, 7635,
10512, 1663, 6957, 3510, 2370, 2865, 3978, 9320, 3247, 9603, 6882,
3186, 10659, 10163, 1153, 9405, 8241, 10040, 2178, 1544, 5559, 420,
8304, 4905, 476, 3531, 5191, 9153, 2399, 8889, 3000, 671, 243,
3016, 3763, 10849, 12262, 9223, 10657, 7205, 11272, 7404, 7575, 8146,
10752, 242, 2678, 3704, 11744, 5019, 3833, 3778, 11899, 773, 5101,
11222, 9888, 442, 2912, 5698, 11935, 4861, 7277, 9808, 11244, 2859,
3780, 11414, 4976, 10682, 7201, 8005, 11287, 5011, 6267, 2987, 2437,
3646, 2566, 10102, 9867, 6250, 5444, 2381, 11796, 8193, 4337, 11854,
1912, 1378, 404, 7644, 1065, 2143, 11121, 5277, 3248, 11082, 2548,
8058, 8907, 11934, 1759, 8582, 3694, 7110, 12144, 6747, 8652, 3459,
2731, 8357, 6378, 7399, 10861, 1696, 9863, 334, 7657, 6534, 11029,
4388, 11560, 3241, 10276, 9000, 9408, 3284, 10200, 7197, 6498, 544,
2468, 339, 11267, 9, 2842, 480, 5331, 7300, 1673, 4278, 4177,
8705, 9764, 1381, 7837, 2396, 8340, 8993, 4354, 130, 6915, 2837,
11462, 5767, 953, 8541, 9813, 118, 7222, 2197, 3006, 9545, 563,
9314, 2625, 11340, 4821, 2639, 7266, 5828, 6561, 7698, 3328, 6512,
1351, 7311, 6553, 8155, 1305, 722, 5146, 4043, 12288, 10810, 2545,
3621, 8747, 8785, 1646, 1212, 5860, 3195, 7203, 10963, 3201, 3014,
955, 11499, 9970, 11119, 3135, 3712, 7443, 9542, 7484, 8736, 9995,
11227, 1635, 9521, 1177, 8034, 140, 10436, 11563, 7678, 4320, 11289,
9198, 12208, 2963, 7393, 2366, 9238};
uint16_t newhope_psis_bitrev_montgomery[PARAM_N] = {
4075, 6974, 7373, 7965, 3262, 5079, 522, 2169, 6364, 1018, 1041,
8775, 2344, 11011, 5574, 1973, 4536, 1050, 6844, 3860, 3818, 6118,
2683, 1190, 4789, 7822, 7540, 6752, 5456, 4449, 3789, 12142, 11973,
382, 3988, 468, 6843, 5339, 6196, 3710, 11316, 1254, 5435, 10930,
3998, 10256, 10367, 3879, 11889, 1728, 6137, 4948, 5862, 6136, 3643,
6874, 8724, 654, 10302, 1702, 7083, 6760, 56, 3199, 9987, 605,
11785, 8076, 5594, 9260, 6403, 4782, 6212, 4624, 9026, 8689, 4080,
11868, 6221, 3602, 975, 8077, 8851, 9445, 5681, 3477, 1105, 142,
241, 12231, 1003, 3532, 5009, 1956, 6008, 11404, 7377, 2049, 10968,
12097, 7591, 5057, 3445, 4780, 2920, 7048, 3127, 8120, 11279, 6821,
11502, 8807, 12138, 2127, 2839, 3957, 431, 1579, 6383, 9784, 5874,
677, 3336, 6234, 2766, 1323, 9115, 12237, 2031, 6956, 6413, 2281,
3969, 3991, 12133, 9522, 4737, 10996, 4774, 5429, 11871, 3772, 453,
5908, 2882, 1805, 2051, 1954, 11713, 3963, 2447, 6142, 8174, 3030,
1843, 2361, 12071, 2908, 3529, 3434, 3202, 7796, 2057, 5369, 11939,
1512, 6906, 10474, 11026, 49, 10806, 5915, 1489, 9789, 5942, 10706,
10431, 7535, 426, 8974, 3757, 10314, 9364, 347, 5868, 9551, 9634,
6554, 10596, 9280, 11566, 174, 2948, 2503, 6507, 10723, 11606, 2459,
64, 3656, 8455, 5257, 5919, 7856, 1747, 9166, 5486, 9235, 6065,
835, 3570, 4240, 11580, 4046, 10970, 9139, 1058, 8210, 11848, 922,
7967, 1958, 10211, 1112, 3728, 4049, 11130, 5990, 1404, 325, 948,
11143, 6190, 295, 11637, 5766, 8212, 8273, 2919, 8527, 6119, 6992,
8333, 1360, 2555, 6167, 1200, 7105, 7991, 3329, 9597, 12121, 5106,
5961, 10695, 10327, 3051, 9923, 4896, 9326, 81, 3091, 1000, 7969,
4611, 726, 1853, 12149, 4255, 11112, 2768, 10654, 1062, 2294, 3553,
4805, 2747, 4846, 8577, 9154, 1170, 2319, 790, 11334, 9275, 9088,
1326, 5086, 9094, 6429, 11077, 10643, 3504, 3542, 8668, 9744, 1479,
1, 8246, 7143, 11567, 10984, 4134, 5736, 4978, 10938, 5777, 8961,
4591, 5728, 6461, 5023, 9650, 7468, 949, 9664, 2975, 11726, 2744,
9283, 10092, 5067, 12171, 2476, 3748, 11336, 6522, 827, 9452, 5374,
12159, 7935, 3296, 3949, 9893, 4452, 10908, 2525, 3584, 8112, 8011,
10616, 4989, 6958, 11809, 9447, 12280, 1022, 11950, 9821, 11745, 5791,
5092, 2089, 9005, 2881, 3289, 2013, 9048, 729, 7901, 1260, 5755,
4632, 11955, 2426, 10593, 1428, 4890, 5911, 3932, 9558, 8830, 3637,
5542, 145, 5179, 8595, 3707, 10530, 355, 3382, 4231, 9741, 1207,
9041, 7012, 1168, 10146, 11224, 4645, 11885, 10911, 10377, 435, 7952,
4096, 493, 9908, 6845, 6039, 2422, 2187, 9723, 8643, 9852, 9302,
6022, 7278, 1002, 4284, 5088, 1607, 7313, 875, 8509, 9430, 1045,
2481, 5012, 7428, 354, 6591, 9377, 11847, 2401, 1067, 7188, 11516,
390, 8511, 8456, 7270, 545, 8585, 9611, 12047, 1537, 4143, 4714,
4885, 1017, 5084, 1632, 3066, 27, 1440, 8526, 9273, 12046, 11618,
9289, 3400, 9890, 3136, 7098, 8758, 11813, 7384, 3985, 11869, 6730,
10745, 10111, 2249, 4048, 2884, 11136, 2126, 1630, 9103, 5407, 2686,
9042, 2969, 8311, 9424, 9919, 8779, 5332, 10626, 1777, 4654, 10863,
7351, 3636, 9585, 5291, 8374, 2166, 4919, 12176, 9140, 12129, 7852,
12286, 4895, 10805, 2780, 5195, 2305, 7247, 9644, 4053, 10600, 3364,
3271, 4057, 4414, 9442, 7917, 2174, 3947, 11951, 2455, 6599, 10545,
10975, 3654, 2894, 7681, 7126, 7287, 12269, 4119, 3343, 2151, 1522,
7174, 7350, 11041, 2442, 2148, 5959, 6492, 8330, 8945, 5598, 3624,
10397, 1325, 6565, 1945, 11260, 10077, 2674, 3338, 3276, 11034, 506,
6505, 1392, 5478, 8778, 1178, 2776, 3408, 10347, 11124, 2575, 9489,
12096, 6092, 10058, 4167, 6085, 923, 11251, 11912, 4578, 10669, 11914,
425, 10453, 392, 10104, 8464, 4235, 8761, 7376, 2291, 3375, 7954,
8896, 6617, 7790, 1737, 11667, 3982, 9342, 6680, 636, 6825, 7383,
512, 4670, 2900, 12050, 7735, 994, 1687, 11883, 7021, 146, 10485,
1403, 5189, 6094, 2483, 2054, 3042, 10945, 3981, 10821, 11826, 8882,
8151, 180, 9600, 7684, 5219, 10880, 6780, 204, 11232, 2600, 7584,
3121, 3017, 11053, 7814, 7043, 4251, 4739, 11063, 6771, 7073, 9261,
2360, 11925, 1928, 11825, 8024, 3678, 3205, 3359, 11197, 5209, 8581,
3238, 8840, 1136, 9363, 1826, 3171, 4489, 7885, 346, 2068, 1389,
8257, 3163, 4840, 6127, 8062, 8921, 612, 4238, 10763, 8067, 125,
11749, 10125, 5416, 2110, 716, 9839, 10584, 11475, 11873, 3448, 343,
1908, 4538, 10423, 7078, 4727, 1208, 11572, 3589, 2982, 1373, 1721,
10753, 4103, 2429, 4209, 5412, 5993, 9011, 438, 3515, 7228, 1218,
8347, 5232, 8682, 1327, 7508, 4924, 448, 1014, 10029, 12221, 4566,
5836, 12229, 2717, 1535, 3200, 5588, 5845, 412, 5102, 7326, 3744,
3056, 2528, 7406, 8314, 9202, 6454, 6613, 1417, 10032, 7784, 1518,
3765, 4176, 5063, 9828, 2275, 6636, 4267, 6463, 2065, 7725, 3495,
8328, 8755, 8144, 10533, 5966, 12077, 9175, 9520, 5596, 6302, 8400,
579, 6781, 11014, 5734, 11113, 11164, 4860, 1131, 10844, 9068, 8016,
9694, 3837, 567, 9348, 7000, 6627, 7699, 5082, 682, 11309, 5207,
4050, 7087, 844, 7434, 3769, 293, 9057, 6940, 9344, 10883, 2633,
8190, 3944, 5530, 5604, 3480, 2171, 9282, 11024, 2213, 8136, 3805,
767, 12239, 216, 11520, 6763, 10353, 7, 8566, 845, 7235, 3154,
4360, 3285, 10268, 2832, 3572, 1282, 7559, 3229, 8360, 10583, 6105,
3120, 6643, 6203, 8536, 8348, 6919, 3536, 9199, 10891, 11463, 5043,
1658, 5618, 8787, 5789, 4719, 751, 11379, 6389, 10783, 3065, 7806,
6586, 2622, 5386, 510, 7628, 6921, 578, 10345, 11839, 8929, 4684,
12226, 7154, 9916, 7302, 8481, 3670, 11066, 2334, 1590, 7878, 10734,
1802, 1891, 5103, 6151, 8820, 3418, 7846, 9951, 4693, 417, 9996,
9652, 4510, 2946, 5461, 365, 881, 1927, 1015, 11675, 11009, 1371,
12265, 2485, 11385, 5039, 6742, 8449, 1842, 12217, 8176, 9577, 4834,
7937, 9461, 2643, 11194, 3045, 6508, 4094, 3451, 7911, 11048, 5406,
4665, 3020, 6616, 11345, 7519, 3669, 5287, 1790, 7014, 5410, 11038,
11249, 2035, 6125, 10407, 4565, 7315, 5078, 10506, 2840, 2478, 9270,
4194, 9195, 4518, 7469, 1160, 6878, 2730, 10421, 10036, 1734, 3815,
10939, 5832, 10595, 10759, 4423, 8420, 9617, 7119, 11010, 11424, 9173,
189, 10080, 10526, 3466, 10588, 7592, 3578, 11511, 7785, 9663, 530,
12150, 8957, 2532, 3317, 9349, 10243, 1481, 9332, 3454, 3758, 7899,
4218, 2593, 11410, 2276, 982, 6513, 1849, 8494, 9021, 4523, 7988,
8, 457, 648, 150, 8000, 2307, 2301, 874, 5650, 170, 9462,
2873, 9855, 11498, 2535, 11169, 5808, 12268, 9687, 1901, 7171, 11787,
3846, 1573, 6063, 3793, 466, 11259, 10608, 3821, 6320, 4649, 6263,
2929};
uint16_t newhope_psis_inv_montgomery[PARAM_N] = {
256, 10570, 1510, 7238, 1034, 7170, 6291, 7921, 11665, 3422, 4000,
2327, 2088, 5565, 795, 10647, 1521, 5484, 2539, 7385, 1055, 7173,
8047, 11683, 1669, 1994, 3796, 5809, 4341, 9398, 11876, 12230, 10525,
12037, 12253, 3506, 4012, 9351, 4847, 2448, 7372, 9831, 3160, 2207,
5582, 2553, 7387, 6322, 9681, 1383, 10731, 1533, 219, 5298, 4268,
7632, 6357, 9686, 8406, 4712, 9451, 10128, 4958, 5975, 11387, 8649,
11769, 6948, 11526, 12180, 1740, 10782, 6807, 2728, 7412, 4570, 4164,
4106, 11120, 12122, 8754, 11784, 3439, 5758, 11356, 6889, 9762, 11928,
1704, 1999, 10819, 12079, 12259, 7018, 11536, 1648, 1991, 2040, 2047,
2048, 10826, 12080, 8748, 8272, 8204, 1172, 1923, 7297, 2798, 7422,
6327, 4415, 7653, 6360, 11442, 12168, 7005, 8023, 9924, 8440, 8228,
2931, 7441, 1063, 3663, 5790, 9605, 10150, 1450, 8985, 11817, 10466,
10273, 12001, 3470, 7518, 1074, 1909, 7295, 9820, 4914, 702, 5367,
7789, 8135, 9940, 1420, 3714, 11064, 12114, 12264, 1752, 5517, 9566,
11900, 1700, 3754, 5803, 829, 1874, 7290, 2797, 10933, 5073, 7747,
8129, 6428, 6185, 11417, 1631, 233, 5300, 9535, 10140, 11982, 8734,
8270, 2937, 10953, 8587, 8249, 2934, 9197, 4825, 5956, 4362, 9401,
1343, 3703, 529, 10609, 12049, 6988, 6265, 895, 3639, 4031, 4087,
4095, 585, 10617, 8539, 4731, 4187, 9376, 3095, 9220, 10095, 10220,
1460, 10742, 12068, 1724, 5513, 11321, 6884, 2739, 5658, 6075, 4379,
11159, 10372, 8504, 4726, 9453, 3106, 7466, 11600, 10435, 8513, 9994,
8450, 9985, 3182, 10988, 8592, 2983, 9204, 4826, 2445, 5616, 6069,
867, 3635, 5786, 11360, 5134, 2489, 10889, 12089, 1727, 7269, 2794,
9177, 1311, 5454, 9557, 6632, 2703, 9164, 10087, 1441, 3717, 531,
3587, 2268, 324, 5313, 759, 1864, 5533, 2546, 7386, 9833, 8427,
4715, 11207, 1601, 7251, 4547, 11183, 12131, 1733, 10781, 10318, 1474,
10744, 5046, 4232, 11138, 10369, 6748, 964, 7160, 4534, 7670, 8118,
8182, 4680, 11202, 6867, 981, 8918, 1274, 182, 26, 7026, 8026,
11680, 12202, 10521, 1503, 7237, 4545, 5916, 9623, 8397, 11733, 10454,
3249, 9242, 6587, 941, 1890, 270, 10572, 6777, 9746, 6659, 6218,
6155, 6146, 878, 1881, 7291, 11575, 12187, 1741, 7271, 8061, 11685,
6936, 4502, 9421, 4857, 4205, 7623, 1089, 10689, 1527, 8996, 10063,
11971, 10488, 6765, 2722, 3900, 9335, 11867, 6962, 11528, 5158, 4248,
4118, 5855, 2592, 5637, 6072, 2623, 7397, 8079, 9932, 4930, 5971,
853, 3633, 519, 8852, 11798, 3441, 11025, 1575, 225, 8810, 11792,
12218, 3501, 9278, 3081, 9218, 4828, 7712, 8124, 11694, 12204, 3499,
4011, 573, 3593, 5780, 7848, 9899, 10192, 1456, 208, 7052, 2763,
7417, 11593, 10434, 12024, 8740, 11782, 10461, 3250, 5731, 7841, 9898,
1414, 202, 3540, 7528, 2831, 2160, 10842, 5060, 4234, 4116, 588,
84, 12, 7024, 2759, 9172, 6577, 11473, 1639, 9012, 3043, 7457,
6332, 11438, 1634, 1989, 9062, 11828, 8712, 11778, 12216, 10523, 6770,
9745, 10170, 4964, 9487, 6622, 946, 8913, 6540, 6201, 4397, 9406,
8366, 9973, 8447, 8229, 11709, 8695, 10020, 3187, 5722, 2573, 10901,
6824, 4486, 4152, 9371, 8361, 2950, 2177, 311, 1800, 9035, 8313,
11721, 3430, 490, 70, 10, 1757, 251, 3547, 7529, 11609, 3414,
7510, 4584, 4166, 9373, 1339, 5458, 7802, 11648, 1664, 7260, 9815,
10180, 6721, 9738, 10169, 8475, 8233, 9954, 1422, 8981, 1283, 5450,
11312, 1616, 3742, 11068, 10359, 4991, 713, 3613, 9294, 8350, 4704,
672, 96, 7036, 9783, 11931, 3460, 5761, 823, 10651, 12055, 10500,
1500, 5481, 783, 3623, 11051, 8601, 8251, 8201, 11705, 10450, 5004,
4226, 7626, 2845, 2162, 3820, 7568, 9859, 3164, 452, 10598, 1514,
5483, 6050, 6131, 4387, 7649, 8115, 6426, 918, 8909, 8295, 1185,
5436, 11310, 8638, 1234, 5443, 11311, 5127, 2488, 2111, 10835, 5059,
7745, 2862, 3920, 560, 80, 1767, 2008, 3798, 11076, 6849, 2734,
10924, 12094, 8750, 1250, 10712, 6797, 971, 7161, 1023, 8924, 4786,
7706, 4612, 4170, 7618, 6355, 4419, 5898, 11376, 10403, 10264, 6733,
4473, 639, 5358, 2521, 9138, 3061, 5704, 4326, 618, 5355, 765,
5376, 768, 7132, 4530, 9425, 3102, 9221, 6584, 11474, 10417, 10266,
12000, 6981, 6264, 4406, 2385, 7363, 4563, 4163, 7617, 9866, 3165,
9230, 11852, 10471, 5007, 5982, 11388, 5138, 734, 3616, 11050, 12112,
6997, 11533, 12181, 10518, 12036, 3475, 2252, 7344, 9827, 4915, 9480,
6621, 4457, 7659, 9872, 6677, 4465, 4149, 7615, 4599, 657, 3605,
515, 10607, 6782, 4480, 640, 1847, 3775, 5806, 2585, 5636, 9583,
1369, 10729, 8555, 10000, 11962, 5220, 7768, 8132, 8184, 9947, 1421,
203, 29, 8782, 11788, 1684, 10774, 10317, 4985, 9490, 8378, 4708,
11206, 5112, 5997, 7879, 11659, 12199, 8765, 10030, 4944, 5973, 6120,
6141, 6144, 7900, 11662, 1666, 238, 34, 3516, 5769, 9602, 8394,
9977, 6692, 956, 10670, 6791, 9748, 11926, 8726, 11780, 5194, 742,
106, 8793, 10034, 3189, 10989, 5081, 4237, 5872, 4350, 2377, 10873,
6820, 6241, 11425, 10410, 10265, 3222, 5727, 9596, 4882, 2453, 2106,
3812, 11078, 12116, 5242, 4260, 11142, 8614, 11764, 12214, 5256, 4262,
4120, 11122, 5100, 11262, 5120, 2487, 5622, 9581, 8391, 8221, 2930,
10952, 12098, 6995, 6266, 9673, 4893, 699, 3611, 4027, 5842, 11368,
1624, 232, 8811, 8281, 1183, 169, 8802, 3013, 2186, 5579, 797,
3625, 4029, 11109, 1587, 7249, 11569, 8675, 6506, 2685, 10917, 12093,
12261, 12285, 1755, 7273, 1039, 1904, 272, 3550, 9285, 3082, 5707,
6082, 4380, 7648, 11626, 5172, 4250, 9385, 8363, 8217, 4685, 5936,
848, 8899, 6538, 934, 1889, 3781, 9318, 10109, 10222, 6727, 961,
5404, 772, 5377, 9546, 8386, 1198, 8949, 3034, 2189, 7335, 4559,
5918, 2601, 10905, 5069, 9502, 3113, 7467, 8089, 11689, 5181, 9518,
8382, 2953, 3933, 4073, 4093, 7607, 8109, 2914, 5683, 4323, 11151,
1593, 10761, 6804, 972, 3650, 2277, 5592, 4310, 7638, 9869, 4921,
703, 1856, 9043, 4803, 9464, 1352, 8971, 11815, 5199, 7765, 6376,
4422, 7654, 2849, 407, 8836, 6529, 7955, 2892, 9191, 1313, 10721,
12065, 12257, 1751, 9028, 8312, 2943, 2176, 3822, 546, 78, 8789,
11789, 10462, 12028, 6985, 4509, 9422, 1346, 5459, 4291, 613, 10621,
6784, 9747, 3148, 7472, 2823, 5670, 810, 7138, 8042, 4660, 7688,
6365, 6176, 6149, 2634, 5643, 9584, 10147, 11983, 5223, 9524, 11894,
10477, 8519, 1217, 3685, 2282, 326, 10580, 3267, 7489, 4581, 2410,
5611, 11335, 6886, 8006, 8166, 11700, 3427, 11023, 8597, 10006, 3185,
455, 65, 5276, 7776, 4622, 5927, 7869, 9902, 11948, 5218, 2501,
5624, 2559, 10899, 1557, 1978, 10816, 10323, 8497, 4725, 675, 1852,
10798, 12076, 10503, 3256, 9243, 3076, 2195, 10847, 12083, 10504, 12034,
10497};

Some files were not shown because too many files have changed in this diff Show More